<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Metabase documentation</title>
</head>
<body>
<center><h1>Metabase documentation</h1></center>
<hr />
<ul>
<p><b>Author:</b> Manuel Lemos (<a href="mailto:mlemos-at-acm.org">mlemos-at-acm.org</a>)</p>
<p><b>Version control:</b> <tt>@(#) $Id: metabase.documentation,v 1.70 2009/11/18 23:02:46 mlemos Exp $</tt></p>
<h2>Contents</h2>
<li><a href="#1.0">Introduction</a></li>
<ul>
<li><a href="#2.1.1">What is Metabase?</a></li>
<li><a href="#2.1.2">Development goals</a></li>
<li><a href="#2.1.3">Package structure</a></li>
<li><a href="#3.1.4">Credits</a></li>
</ul>
<li><a href="#4.0">Metabase data types</a></li>
<ul>
<li><a href="#5.1.1">Text data type</a></li>
<li><a href="#5.1.2">Boolean data type</a></li>
<li><a href="#5.1.3">Integer data type</a></li>
<li><a href="#5.1.4">Decimal data type</a></li>
<li><a href="#5.1.5">Float data type</a></li>
<li><a href="#5.1.6">Date data type</a></li>
<li><a href="#5.1.7">Time data type</a></li>
<li><a href="#5.1.8">Time stamp data type</a></li>
<li><a href="#5.1.9">Large object (file) data types</a></li>
</ul>
<li><a href="#5.0">Applications programming interface (API)</a></li>
<ul>
<li><a href="#6.1.1">Calling Metabase API</a></li>
<ul>
<li><a href="#7.2.1">Calling the API global functions</a></li>
<li><a href="#8.2.2">Calling the driver object functions directly</a></li>
</ul>
<li><a href="#9.1.2">Database interface setup</a></li>
<ul>
<li><a href="#10.2.0">MetabaseSetupDatabase</a></li>
<li><a href="#17.2.0">MetabaseSetupDatabaseObject</a></li>
<li><a href="#22.2.0">MetabaseParseConnectionArguments</a></li>
<li><a href="#23.2.0">MetabaseCloseSetup</a></li>
<li><a href="#24.2.0">MetabaseSetDatabase</a></li>
<li><a href="#25.2.0">MetabaseError</a></li>
<li><a href="#26.2.0">MetabaseSetErrorHandler</a></li>
<li><a href="#28.2.0">MetabaseSupport</a></li>
</ul>
<li><a href="#30.1.3">Query execution</a></li>
<ul>
<li><a href="#31.2.0">MetabaseQuery</a></li>
<li><a href="#32.2.0">MetabaseReplace</a></li>
<li><a href="#34.2.1">Data type conversion</a></li>
<ul>
<li><a href="#35.3.0">MetabaseGetTextFieldValue</a></li>
<li><a href="#36.3.0">MetabaseGetBooleanFieldValue</a></li>
<li><a href="#37.3.0">MetabaseGetDecimalFieldValue</a></li>
<li><a href="#38.3.0">MetabaseGetFloatFieldValue</a></li>
<li><a href="#39.3.0">MetabaseGetDateFieldValue</a></li>
<li><a href="#40.3.0">MetabaseGetTimeFieldValue</a></li>
<li><a href="#41.3.0">MetabaseGetTimestampFieldValue</a></li>
<li><a href="#42.3.0">MetabaseNow</a></li>
<li><a href="#43.3.0">MetabaseToday</a></li>
<li><a href="#44.3.0">MetabaseTime</a></li>
</ul>
<li><a href="#45.2.2">Pattern matching</a></li>
<ul>
<li><a href="#46.3.0">MetabaseBeginsWith</a></li>
<li><a href="#47.3.0">MetabaseEndsWith</a></li>
<li><a href="#48.3.0">MetabaseContains</a></li>
<li><a href="#49.3.0">MetabaseMatchPattern</a></li>
</ul>
<li><a href="#50.2.3">Auto-incremented keys</a></li>
<ul>
<li><a href="#51.3.0">MetabaseGetNextKey</a></li>
<li><a href="#54.3.0">MetabaseGetInsertedKey</a></li>
</ul>
<li><a href="#55.2.4">Prepared queries</a></li>
<ul>
<li><a href="#56.3.0">MetabasePrepareQuery</a></li>
<li><a href="#57.3.0">MetabaseFreePreparedQuery</a></li>
<li><a href="#58.3.0">MetabaseExecuteQuery</a></li>
<li><a href="#59.3.0">MetabaseQuerySet</a></li>
<li><a href="#61.3.0">MetabaseQuerySetNull</a></li>
<li><a href="#62.3.0">MetabaseQuerySetText</a></li>
<li><a href="#63.3.0">MetabaseQuerySetBoolean</a></li>
<li><a href="#64.3.0">MetabaseQuerySetInteger</a></li>
<li><a href="#65.3.0">MetabaseQuerySetDecimal</a></li>
<li><a href="#66.3.0">MetabaseQuerySetFloat</a></li>
<li><a href="#67.3.0">MetabaseQuerySetDate</a></li>
<li><a href="#68.3.0">MetabaseQuerySetTime</a></li>
<li><a href="#69.3.0">MetabaseQuerySetTimestamp</a></li>
<li><a href="#70.3.0">MetabaseQuerySetCLOB</a></li>
<li><a href="#71.3.0">MetabaseQuerySetBLOB</a></li>
<li><a href="#72.3.0">MetabaseQuerySetKey</a></li>
</ul>
<li><a href="#73.2.4">MetabaseSetSelectedRowRange</a></li>
</ul>
<li><a href="#74.1.4">Query result handling</a></li>
<ul>
<li><a href="#75.2.0">MetabaseAffectedRows</a></li>
<li><a href="#76.2.0">MetabaseResultIsNull</a></li>
<li><a href="#77.2.0">MetabaseFetchResult</a></li>
<li><a href="#78.2.0">MetabaseFetchBooleanResult</a></li>
<li><a href="#79.2.0">MetabaseFetchDecimalResult</a></li>
<li><a href="#80.2.0">MetabaseFetchFloatResult</a></li>
<li><a href="#81.2.0">MetabaseFetchDateResult</a></li>
<li><a href="#82.2.0">MetabaseFetchTimeResult</a></li>
<li><a href="#83.2.0">MetabaseFetchTimestampResult</a></li>
<li><a href="#84.2.0">MetabaseFetchCLOBResult</a></li>
<li><a href="#85.2.0">MetabaseFetchBLOBResult</a></li>
<li><a href="#86.2.0">MetabaseEndOfResult</a></li>
<li><a href="#87.2.0">MetabaseNumberOfRows</a></li>
<li><a href="#88.2.0">MetabaseNumberOfColumns</a></li>
<li><a href="#89.2.0">MetabaseGetColumnNames</a></li>
<li><a href="#90.2.0">MetabaseFreeResult</a></li>
</ul>
<li><a href="#91.1.5">Large object data manipulation</a></li>
<ul>
<li><a href="#92.2.0">MetabaseCreateLOB</a></li>
<li><a href="#99.2.0">MetabaseReadLOB</a></li>
<li><a href="#100.2.0">MetabaseEndOfLOB</a></li>
<li><a href="#101.2.0">MetabaseDestroyLOB</a></li>
<li><a href="#102.2.0">MetabaseLOBError</a></li>
<li><a href="#103.2.0">MetabaseEndOfLOB</a></li>
<li><a href="#104.2.0">MetabaseDestroyLOB</a></li>
</ul>
<li><a href="#105.1.6">Query result set bulk data fetching</a></li>
<ul>
<li><a href="#107.2.0">MetabaseSetResultTypes</a></li>
<li><a href="#108.2.0">MetabaseFetchResultArray</a></li>
<li><a href="#109.2.0">MetabaseFetchResultField</a></li>
<li><a href="#110.2.0">MetabaseFetchResultRow</a></li>
<li><a href="#111.2.0">MetabaseFetchResultColumn</a></li>
<li><a href="#112.2.0">MetabaseFetchResultAll</a></li>
<li><a href="#113.2.0">MetabaseQueryField</a></li>
<li><a href="#114.2.0">MetabaseQueryRow</a></li>
<li><a href="#115.2.0">MetabaseQueryColumn</a></li>
<li><a href="#116.2.0">MetabaseQueryAll</a></li>
</ul>
<li><a href="#117.1.7">Transaction management</a></li>
<ul>
<li><a href="#118.2.0">MetabaseAutoCommitTransactions</a></li>
<li><a href="#119.2.0">MetabaseCommitTransaction</a></li>
<li><a href="#120.2.0">MetabaseRollbackTransaction</a></li>
</ul>
<li><a href="#121.1.8">Database schema objects management</a></li>
<ul>
<li><a href="#122.2.0">Databases</a></li>
<ul>
<li><a href="#123.3.0">MetabaseCreateDatabase</a></li>
<li><a href="#124.3.0">MetabaseDropDatabase</a></li>
</ul>
<li><a href="#125.2.0">Tables</a></li>
<ul>
<li><a href="#126.3.0">MetabaseGetTextFieldTypeDeclaration</a></li>
<li><a href="#128.3.0">MetabaseGetBooleanFieldTypeDeclaration</a></li>
<li><a href="#130.3.0">MetabaseGetIntegerFieldTypeDeclaration</a></li>
<li><a href="#132.3.0">MetabaseGetDecimalFieldTypeDeclaration</a></li>
<li><a href="#134.3.0">MetabaseGetFloatFieldTypeDeclaration</a></li>
<li><a href="#136.3.0">MetabaseGetDateFieldTypeDeclaration</a></li>
<li><a href="#138.3.0">MetabaseGetTimeFieldTypeDeclaration</a></li>
<li><a href="#140.3.0">MetabaseGetTimestampFieldTypeDeclaration</a></li>
<li><a href="#142.3.0">MetabaseGetCLOBFieldTypeDeclaration</a></li>
<li><a href="#144.3.0">MetabaseGetBLOBFieldTypeDeclaration</a></li>
<li><a href="#146.3.0">MetabaseCreateTable</a></li>
<li><a href="#153.3.0">MetabaseCreateDetailedTable</a></li>
<li><a href="#156.3.0">MetabaseDropTable</a></li>
<li><a href="#157.3.0">MetabaseDropDetailedTable</a></li>
<li><a href="#158.3.0">MetabaseAlterTable</a></li>
</ul>
<li><a href="#170.2.0">Sequences</a></li>
<ul>
<li><a href="#171.3.0">MetabaseCreateSequence</a></li>
<li><a href="#172.3.0">MetabaseDropSequence</a></li>
<li><a href="#173.3.0">MetabaseGetSequenceNextValue</a></li>
<li><a href="#174.3.0">MetabaseGetSequenceCurrentValue</a></li>
</ul>
<li><a href="#175.2.0">Indexes</a></li>
<ul>
<li><a href="#176.3.0">MetabaseCreateIndex</a></li>
<li><a href="#182.3.0">MetabaseDropIndex</a></li>
</ul>
<li><a href="#183.2.0">Schema reverse engineering</a></li>
<ul>
<li><a href="#184.3.0">MetabaseListTables</a></li>
<li><a href="#185.3.0">MetabaseListTableFields</a></li>
<li><a href="#186.3.0">MetabaseGetTableFieldDefinition</a></li>
<li><a href="#187.3.0">MetabaseListTableKeys</a></li>
<li><a href="#188.3.0">MetabaseGetTableKeyDefinition</a></li>
<li><a href="#189.3.0">MetabaseListTableIndexes</a></li>
<li><a href="#190.3.0">MetabaseGetTableIndexDefinition</a></li>
<li><a href="#191.3.0">MetabaseListSequences</a></li>
<li><a href="#192.3.0">MetabaseGetSequenceDefinition</a></li>
</ul>
</ul>
<li><a href="#193.1.9">Debugging</a></li>
<ul>
<li><a href="#194.2.0">MetabaseCaptureDebugOutput</a></li>
<li><a href="#195.2.0">MetabaseDebugOutput</a></li>
<li><a href="#196.2.0">MetabaseDebug</a></li>
</ul>
</ul>
<li><a href="#197.0">DBMS specific drivers</a></li>
<ul>
<li><a href="#198.1.0">Driver class functions</a></li>
<ul>
<li><a href="#200.2.0">Setup</a></li>
<li><a href="#201.2.0">Close</a></li>
</ul>
<li><a href="#202.1.1">Driver object variables</a></li>
<li><a href="#203.1.2">Driver class extensions</a></li>
<ul>
<li><a href="#204.2.0">Manager extension</a></li>
</ul>
<li><a href="#206.1.3">Available drivers</a></li>
<ul>
<li><a href="#208.2.0">Interbase</a></li>
<li><a href="#212.2.1">Informix</a></li>
<li><a href="#217.2.2">Microsoft SQL Server</a></li>
<li><a href="#222.2.0">Mini-SQL</a></li>
<li><a href="#226.2.1">MySQL</a></li>
<li><a href="#230.2.2">ODBC - Open Database Connectivity</a></li>
<li><a href="#234.2.3">Microsoft Access via ODBC</a></li>
<li><a href="#238.2.4">Oracle using Oracle Call Interface (oci)</a></li>
<li><a href="#242.2.5">PostgreSQL</a></li>
<li><a href="#246.2.6">SQLite</a></li>
</ul>
</ul>
<li><a href="#250.0">DBMS specific drivers conformance test suite</a></li>
<ul>
<li><a href="#251.1.0">Software quality assurance</a></li>
<li><a href="#251.1.1">Metabase software quality certification methods</a></li>
<li><a href="#251.1.2">Metabase test suite</a></li>
<li><a href="#251.1.3">Supported tests types</a></li>
<ul>
<li><a href="#252.2.0">Storing and retrieving different data types</a></li>
<li><a href="#252.2.1">Retrieving query result data using bulk fetching functions</a></li>
<li><a href="#252.2.2">Prepared queries</a></li>
<li><a href="#252.2.3">Query result set metadata retrieval</a></li>
<li><a href="#252.2.4">Storing and retrieving NULL values</a></li>
<li><a href="#252.2.5">Escaping text values with special characters</a></li>
<li><a href="#252.2.6">Selecting query result row ranges</a></li>
<li><a href="#252.2.7">Sequences</a></li>
<li><a href="#252.2.8">Count of rows affected by a query</a></li>
<li><a href="#252.2.9">Transactions</a></li>
<li><a href="#252.2.10">Updating a table with the SQL REPLACE query</a></li>
<li><a href="#252.2.11">Storing and retrieving data in large object fields</a></li>
<li><a href="#252.2.12">Storing and retrieving data in large object fields from and to files</a></li>
<li><a href="#252.2.13">Storing and retrieving NULL values in large object fields</a></li>
<li><a href="#252.2.14">Retrieving auto-increment keys in direct queries</a></li>
<li><a href="#252.2.15">Retrieving auto-increment keys in prepared queries</a></li>
<li><a href="#252.2.16">Match patterns</a></li>
</ul>
<li><a href="#252.1.4">Known conformance failure issues</a></li>
<ul>
<li><a href="#253.2.0">Interbase</a></li>
<li><a href="#253.2.1">Informix</a></li>
<li><a href="#253.2.2">Mini-SQL</a></li>
<li><a href="#253.2.3">MySQL</a></li>
<li><a href="#253.2.4">ODBC</a></li>
<li><a href="#253.2.5">PostgreSQL</a></li>
<li><a href="#253.2.6">Oracle</a></li>
</ul>
</ul>
<li><a href="#253.0">Schema description parser</a></li>
<ul>
<li><a href="#254.1.0">Schema description</a></li>
<ul>
<li><a href="#255.2.0">Introduction to XML</a></li>
<li><a href="#255.2.1">Schema description format and XML</a></li>
<li><a href="#255.2.2">Schema description data structure</a></li>
<ul>
<li><a href="#256.3.0">database</a></li>
<li><a href="#257.3.1">table</a></li>
<li><a href="#267.3.2">declaration</a></li>
<li><a href="#267.3.3">field</a></li>
<li><a href="#270.3.4">index</a></li>
<li><a href="#271.3.5">index field</a></li>
<li><a href="#275.3.6">primarykey</a></li>
<li><a href="#278.3.7">initialization</a></li>
<li><a href="#278.3.8">insert</a></li>
<li><a href="#278.3.9">sequence</a></li>
<li><a href="#279.3.10">sequence on table field</a></li>
<li><a href="#282.3.11">variable</a></li>
</ul>
<li><a href="#282.2.3">Schema description parser class</a></li>
<ul>
<li><a href="#283.3.1">Functions</a></li>
<ul>
<li><a href="#284.4.0">Parse</a></li>
<li><a href="#285.4.0">ParseStream</a></li>
</ul>
<li><a href="#286.3.2">Variables</a></li>
<ul>
<li><a href="#287.4.1">stream_buffer_size</a></li>
<li><a href="#287.4.2">error_number</a></li>
<li><a href="#288.4.3">error</a></li>
<li><a href="#288.4.4">error_line</a></li>
<li><a href="#288.4.5">error_column</a></li>
<li><a href="#288.4.6">error_byte_index</a></li>
<li><a href="#288.4.7">variables</a></li>
<li><a href="#288.4.8">fail_on_invalid_names</a></li>
<li><a href="#288.4.9">database</a></li>
</ul>
</ul>
</ul>
</ul>
<li><a href="#288.0">Database manager</a></li>
<ul>
<li><a href="#289.1.1">Functions</a></li>
<ul>
<li><a href="#290.2.0">AlterDatabase</a></li>
<li><a href="#291.2.0">DumpDatabase</a></li>
<li><a href="#293.2.0">ParseDatabaseDefinitionFile</a></li>
<li><a href="#294.2.0">DumpDatabaseChanges</a></li>
<li><a href="#295.2.0">UpdateDatabase</a></li>
<li><a href="#296.2.0">DumpDatabaseContents</a></li>
<li><a href="#297.2.0">GetDefinitionFromDatabase</a></li>
</ul>
<li><a href="#298.1.2">Variables</a></li>
<ul>
<li><a href="#299.2.1">fail_on_invalid_names</a></li>
<li><a href="#299.2.2">error</a></li>
<li><a href="#299.2.3">warnings</a></li>
<li><a href="#299.2.4">database_definition</a></li>
</ul>
</ul>
</ul>
<hr />
<h1><a name="1.0">Introduction</a></h1>
<ul>
<h2><li><a name="2.1.1">What is <b>Metabase</b>?</a></li></h2>
<p><b>Metabase</b> is a PHP package intended to provide <i>DBMS</i> (<i>DataBase Management System</i>) independent means to install, access and maintain <i>SQL</i> based databases.</p>
<h2><li><a name="2.1.2">Development goals</a></li></h2>
<p>The development of <b>Metabase</b> has two main goals.  One is to provide a unified programming interface to access distinct <i>SQL</i> based <i>DBMS</i>.  Using the same interface, programmers may develop database applications that may run with <i>DBMS</i> of different vendors:  Oracle, Sybase, My<i>SQL</i>, Microsoft <i>SQL</i> Server, etc..</p>
<p>The second goal is to provide a tool to install and maintain database schemas using the same <i>DBMS</i> independent database interface.  Using this tool, developers may design and evolve database schemas that serve the needs of their applications without having to worry on how to install or upgrade them on each type of <i>DBMS</i> that is used.</p>
<h2><li><a name="2.1.3">Package structure</a></li></h2>
<ul>
<p><b>Metabase</b> is divided in several parts:</p>
<h3><li><i>DBMS</i> independent programming interface</li></h3>
<p>Consists of a class that is able to instantiate the driver classes.  There is also a set of functions that the applications should call to execute several different types of operations needed to access to the databases.</p>
<h3><li><i>DBMS</i> specific drivers</li></h3>
<p>Consists of a set of driver classes that implement functions that are called by the interface functions to implement database access aspects that are <i>DBMS</i> specific.</p>
<h3><li><i>DBMS</i> specific schema manager driver extensions</li></h3>
<p>Consists of a set of driver extension classes that implement functions that are called by the main driver class to implement schema management functions.</p>
<h3><li>Drivers conformance test suite</li></h3>
<p>Consists of a script that performs a set of tests to verify if the <i>DBMS</i> specific drivers work in conformance with the way they are expected to work, thus without any bugs that may affect the <b>Metabase</b> applications that use them.</p>
<h3><li>Schema description parser</li></h3>
<p>Class that is able to parse database schema description defined in a custom XML based format.  The class produces a data structure that has the information of the different database objects described in the schema description file.</p>
<h3><li>Database manager</li></h3>
<p>Class that is able to take the schema description data structure generated by the parser class and then create a database with the specified <i>DBMS</i> using the interface functions.</p>
<p>This class is able to compare the data structures of two versions of the same schema description (the currently installed in the <i>DBMS</i> and a new one to upgrade to) and execute the necessary operations to alter the database schema without disturbing any data stored after the database was installed or its schema was upgrade for the last time.</p>
</ul>
<h2><li><a name="3.1.4">Credits</a></li></h2>
<ul>
<h3><li>Manuel Lemos</li></h3>
<p><tt><a href="mailto:mlemos-at-acm.org">mlemos-at-acm.org</a></tt></p>
<p>Design, implementation and documentation of most of Metabase.</p>
<h3><li>Pierre-henri Delaval</li></h3>
<p><tt><a href="mailto:pierre-henri-at-wanadoo.be">pierre-henri-at-wanadoo.be</a></tt></p>
<p>Informix driver.</p>
<h3><li>Meir Kriheli</li></h3>
<p><tt><a href="mailto:mksoft-at-netvision.net.il">mksoft-at-netvision.net.il</a></tt></p>
<p>Interbase driver.</p>
<h3><li>Aral Balkan</li></h3>
<p><tt><a href="mailto:aral-at-aralbalkan.com">aral-at-aralbalkan.com</a></tt></p>
<p>EditPlus templates for editing database schema XML files.</p>
<h3><li>Andreas Aderhold Thyrell</li></h3>
<p><tt><a href="mailto:a.aderhold-at-thyrell.de">a.aderhold-at-thyrell.de</a></tt></p>
<p>Query result set metadata retrieval functions.</p>
<h3><li>Lukas Smith and Christopher Linn</li></h3>
<p><tt><a href="mailto:smith-at-dybnet.de">smith-at-dybnet.de</a></tt><br />
<tt><a href="mailto:clinn-at-dybnet.de">clinn-at-dybnet.de</a></tt></p>
<p>Query result set bulk data retrieval functions.</p>
<h3><li>Stefano Locati</li></h3>
<p><tt><a href="mailto:stefano-at-obliquid.it">stefano-at-obliquid.it</a></tt></p>
<p>Schema XML style sheet</p>
<h3><li>Jeroen Derks</li></h3>
<p><tt><a href="mailto:jeroen-at-derks.it">jeroen-at-derks.it</a></tt></p>
<p>Database schema reverse engineering and SQLite driver</p>
<h3><li>Svemir Brkic</li></h3>
<p><tt><a href="mailto:svemir-at-symplicity.com">svemir-at-symplicity.com</a></tt></p>
<p>Microsoft Access ODBC sub-driver</p>
<h3><li>John Walton</li></h3>
<p><tt><a href="mailto:admin-at-ryefc.com">admin-at-ryefc.com</a></tt></p>
<p>SQLite driver auto-increment and primary key support</p>
</ul>
</ul>
<hr />
<h1><a name="4.0"><b>Metabase</b> data types</a></h1>
<ul>
<p>All <i>DBMS</i> provide multiple choice of data types for the information that can be stored in their database table fields.  However, the set of data types made available varies from <i>DBMS</i> to <i>DBMS</i>.</p>
<p>To simplify the interface with the <i>DBMS</i> supported by <b>Metabase</b> it was defined a base set of data types that applications may access independently of the underlying <i>DBMS</i>.</p>
<p>The <b>Metabase</b> applications programming interface takes care of mapping data types when managing database options.  It is also able to convert that is sent to and received from the underlying <i>DBMS</i> using the respective driver.</p>
<h2><li><a name="5.1.1">Text data type</a></li></h2>
<p>The text data type is available with two options for the length: one that is explicitly length limited and another of undefined length that should be as large as the database allows.</p>
<p>The length limited option is the most recommended for efficiency reasons.  The undefined length option allows very large fields but may prevent the use of indexes and may not allow sorting on fields of its type.</p>
<p>The fields of this type should be able to handle 8 bit characters.  Drivers take care of <i>DBMS</i> specific escaping of characters of special meaning with the values of the strings to be converted to this type.</p>
<h2><li><a name="5.1.2">Boolean data type</a></li></h2>
<p>The boolean data type represents only two values that can be either <tt>1</tt> or <tt>0</tt>.  Do not assume that these data types are stored as integers because some <i>DBMS</i> drivers may implement this type with single character text fields for a matter of efficient.  Ternary logic is possible by using <tt>NULL</tt> as the third possible value that may be assigned to fields of this type.</p>
<h2><li><a name="5.1.3">Integer data type</a></li></h2>
<p>The integer data type may store integer values as large as each <i>DBMS</i> may handle.  Fields of this type may be created optionally as unsigned integers but not all <i>DBMS</i> support it.  Therefore, such option may be ignored.  Truly portable applications should not rely on the availability of this option.</p>
<h2><li><a name="5.1.4">Decimal data type</a></li></h2>
<p>The decimal data type may store decimal numbers accurately with a fixed number of decimal places.  This data type is suitable for representing accurate values like currency amounts.</p>
<p>Some <i>DBMS</i> drivers may emulate the decimal data type using integers.  Such drivers need to know in advance how many decimal places that should be used to perform eventual scale conversion when storing and retrieving values from a database. Despite this, applications may use arithmetic expressions and functions with the values stored on decimal type fields as long as any constant values that are used in the expressions are also converted with the respective <b>Metabase</b> conversion functions.</p>
<p>The number of places that are used to the left and the right of the decimal point is pre-determined and fixed for all decimal values stored in the same database.  By default, <b>Metabase</b> uses 2 places to the right of the decimal point, but this may be changed when setting the database connection.  The number of places available to the right of the decimal point depend on the <i>DBMS</i>.</p>
<p>It is not recommended to change the number places used to represent decimal values in database after it is installed. <b>Metabase</b> does not keep track of changes in the number of decimal places.</p>
<h2><li><a name="5.1.5">Float data type</a></li></h2>
<p>The float data type may store floating point decimal numbers. This data type is suitable for representing numbers within a large scale range that do not require high accuracy.  The scale and the precision limits of the values that may be stored in a database depends on the <i>DBMS</i> that it is used.</p>
<h2><li><a name="5.1.6">Date data type</a></li></h2>
<p>The date data type may represent dates with year, month and day.  <i>DBMS</i> independent representation of dates is accomplished by using text strings formatted according to the <i>IS0 8601</i> standard.</p>
<p>The format defined by the <i>ISO 8601</i> standard for dates is <tt>YYYY-MM-DD</tt> where <tt>YYYY</tt> is the number of the year (<i>Gregorian</i> calendar), <tt>MM</tt> is the number of the month from 1 to 12 and <tt>DD</tt> is the number of the day from 1 to 31.  Months or days numbered below 10 should be padded on the left with <tt>0</tt>.</p>
<p>Some <i>DBMS</i> have native support for date formats, but for others the <i>DBMS</i> driver may have to represent them as integers or text values.  In any case, it is always possible to make comparisons between date values as well sort query results by fields of this type.</p>
<h2><li><a name="5.1.7">Time data type</a></li></h2>
<p>The time data type may represent the time of a given moment of the day.  <i>DBMS</i> independent representation of the time of the day is also accomplished by using text strings formatted according to the <i>IS0 8601</i> standard.</p>
<p>The format defined by the <i>ISO 8601</i> standard for the time of the day is <tt>HH:MI:SS</tt> where <tt>HH</tt> is the number of hour the day from 0 to 23 and <tt>MI</tt> and <tt>SS</tt> are respectively the number of the minute and of the second from 0 to 59.  Hours, minutes and seconds numbered below 10 should be padded on the left with <tt>0</tt>.</p>
<p>Some <i>DBMS</i> have native support for time of the day formats, but for others the <i>DBMS</i> driver may have to represent them as integers or text values.  In any case, it is always possible to make comparisons between time values as well sort query results by fields of this type.</p>
<h2><li><a name="5.1.8">Time stamp data type</a></li></h2>
<p>The time stamp data type is a mere combination of the date and the time of the day data types.  The representation of values of the time stamp type is accomplished by joining the date and time string values in a single string joined by a space.  Therefore, the format template is <tt>YYYY-MM-DD HH:MI:SS</tt>.  The represented values obey the same rules and ranges described for the date and time data types.</p>
<h2><li><a name="5.1.9">Large object (file) data types</a></li></h2>
<p>The large object data types are meant to store data of undefined length that may be to large to store in text fields, like data that is usually stored in files.</p>
<p><b>Metabase</b> supports two types of large object fields: Character Large OBjects (<i>CLOBs</i>) and Binary Large OBjects (<i>BLOBs</i>). <i>CLOB</i> fields are meant to store only data made of printable <i>ASCII</i> characters. <i>BLOB</i> fields are meant to store all types of data.</p>
<p>Large object fields are usually not meant to be used as parameters of query search clause (<tt>WHERE</tt>) unless the underlying <i>DBMS</i> supports a feature usually known as <i>&quot;full text search&quot;</i>.</p>
</ul>
<hr />
<h1><a name="5.0">Applications programming interface (<i>API</i>)</a></h1>
<ul>
<h2><li><a name="6.1.1">Calling Metabase API</a></li></h2>
<ul>
<p>The applications programming interface consists of one set of functions that call the appropriate <i>DBMS</i> specific functions to implement several database access functions.</p>
<p>The <b>Metabase</b> API function can be called in two different forms: calling the API global functions or calling the driver object functions directly. Both forms are always available and may be used at the same time in the programs that use <b>Metabase</b>.</p>
<h3><li><a name="7.2.1">Calling the API global functions</a></li></h3>
<ul>
<p>The original form to call <b>Metabase</b> API functions is through a set of global functions that have their names starting with the <tt>Metabase</tt> prefix.</p>
<p>These functions make indirect calls to the chosen driver class object. They always take as first parameter an integer value that works as a handle to identify the driver class object that is meant to be called.</p>
<p>If for some reason you need to use <b>Metabase</b> under PHP 3 or you need write code that works under PHP 3, using these functions is your only option.</p>
<p>To use this form of calling <b>Metabase</b> API you need to use first the function <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> described below.</p>
</ul>
<h3><li><a name="8.2.2">Calling the driver object functions directly</a></li></h3>
<ul>
<p>Another form to call <b>Metabase</b> API functions is calling the driver class object functions directly. The driver class functions to call have the exact same names as the API global functions, except that they do not have the <tt>Metabase</tt> prefix nor need the database handler integer as first argument.</p>
<p>To use this form you need to use first the function <tt><a href="#function_MetabaseSetupDatabaseObject">MetabaseSetupDatabaseObject</a></tt> described below.  This function only works under PHP 4 or better because it returns a reference to a driver class object that is stored in a private global variable.</p>
<p>Calling driver functions directly works slightly faster. However, you need to be careful to always pass references to the object to other functions or objects because when you pass objects by value you end with two distinct copies of the same driver object that may lead to inconsistencies in the use of the driver class functions.</p>
<p>If you do not want or you are not sure of how to safely pass or assign objects by reference, just call the driver object functions from your main scripts or use the API global functions instead.</p>
</ul>
</ul>
<h2><li><a name="9.1.2">Database interface setup</a></li></h2>
<ul>
<h3><a name="10.2.0"><a name="function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=MetabaseSetupDatabase($arguments, &amp;$database)</tt></p>
<h4>Purpose</h4>
<p>Setup a database interface instance.  Applications need call this function first to obtain a database interface instance handle.  This handle is needed to call all the other database interface functions.</p>
<p>Usually, this function does not establish a database connection.  Database connections are established by the <i>DBMS</i> drivers whenever they are needed.</p>
<h4>Usage</h4>
<p>The <tt>$arguments</tt> argument is an associative array that takes pairs of tag names and values that define which <i>DBMS</i> driver is meant to be used and the parameters needed to setup that driver.  Currently, the types of supported arguments are as follows:</p>
<ul>
<p><tt><li>Connection</li></tt></p>
<p>The database connection setup arguments may be specified individually or all at once with the <tt>Connection</tt> argument. This argument consists of a connection string like an URL of the following format:</p>
<p><tt><b>Type</b>://<b>User</b>:<b>Password</b>@<b>Host</b>:<b>Port</b>/<b>Database</b>?<br />
<b>Options</b>/option1=value1&amp;<b>Options</b>/option2=value2</tt>...</p>
<p>You may use this argument to replace all or part of the other arguments. Values specified in this connection string prevail over values specified in the separate arguments.</p>
<p>The <tt>Type</tt> argument is required. If the <tt>User</tt> argument is specified, the <tt>@</tt> character is necessary. If the <tt>Password</tt> is specified, the <tt>:</tt> character before it is required. If the <tt>Port</tt> argument is specified, the <tt>:</tt> before it is required.</p>
<p>The <tt>Options</tt> argument forms an option array where the indexes are the names of the database specific options specified after the respective <tt>/</tt> character. The values of the respective options follow the <tt>=</tt> character until the <tt>&amp;</tt> character or the end of the <tt>Connection</tt> URL.</p>
<p>Keep in mind that argument values with characters that have special meaning in URLs like <tt>&amp;</tt>, <tt>=</tt>, <tt>?</tt> and <tt>%</tt> need to be properly escaped using a <tt>%</tt> followed by the hexadecimal representation of the ASCII code of the respective characters, so they become respectively: <tt>%26</tt>, <tt>%3D</tt>, <tt>%3F</tt> and <tt>%25</tt>. If you may have characters like these in an argument value, it may be simpler to encode them with the <i>PHP</i> function <tt><a href="http://www.php.net/urlencode">UrlEncode</a></tt>.</p>
<p><b>Default value:</b> none</p>
<p><b>Example:</b> <tt>mysql://root@localhost/driver_test?<br />
Options/Port=/var/lib/mysql/mysql.sock</tt></p>
<p><tt><li>Type</li></tt></p>
<p>Designation of the type of <i>DBMS</i> driver that is meant to be used.  The designation of the currently built-in supported drivers is as follows:</p>
<ul>
<p><li><tt>ibase         - </tt>Interbase</li></p>
<p><li><tt>ifx           - </tt>Informix</li></p>
<p><li><tt>msql          - </tt>Mini-SQL</li></p>
<p><li><tt>mssql         - </tt>Microsoft SQL Server</li></p>
<p><li><tt>mysql         - </tt>MySQL</li></p>
<p><li><tt>odbc          - </tt>ODBC</li></p>
<p><li><tt>odbc-msaccess - </tt>Microsoft Access via ODBC</li></p>
<p><li><tt>oci           - </tt>Oracle via Oracle Call Interface</li></p>
<p><li><tt>pgsql         - </tt>PostgreSQL</li></p>
<p><li><tt>sqlite        - </tt>SQLite</li></p>
</ul>
<p><b>Default value:</b> not specified</p>
<p><li><tt>Include</tt> (required if the argument <tt>Type</tt> is missing)</li></p>
<p>Name of the file of the <i>DBMS</i> driver class to be included if the <tt>Type</tt> argument is not specified.</p>
<p><b>Default value:</b> not specified</p>
<p><li><tt>IncludedConstant</tt> (required if the argument <tt>Type</tt> is missing)</li></p>
<p>Name of the constant that is defined within the specified <i>DBMS</i> driver class file.  This function will check if the specified name is defined to prevent multiple inclusions of the driver class file.  This argument is ignored if the <tt>Type</tt> argument is specified.</p>
<p><b>Default value:</b> not specified</p>
<p><li><tt>ClassName</tt> (required if the argument <tt>Type</tt> is missing)</li></p>
<p>Name of the <i>DBMS</i> driver class.  This argument is ignored if the <tt>Type</tt> argument is specified.</p>
<p><b>Default value:</b> not specified</p>
<p><li><tt>IncludePath</tt></li></p>
<p>Path of the directory where the driver class include file may be found. This argument is required if <b>Metabase</b> include files are not located in the same directory as the current script directory that is running.</p>
<p><b>Default value:</b> <tt>&quot;&quot;</tt></p>
<p><li><tt>User</tt></li></p>
<p>Access name of the user that has to login to have access to the <i>DBMS</i>.  This argument may be ignored by some <i>DBMS</i> drivers.</p>
<p><b>Default value:</b> <tt>&quot;&quot;</tt></p>
<p><li><tt>Password</tt></li></p>
<p>Password of the user that is has to login to have access to the <i>DBMS</i>.  This argument may be ignored by some <i>DBMS</i> drivers.</p>
<p><b>Default value:</b> <tt>&quot;&quot;</tt></p>
<p><li><tt>Host</tt></li></p>
<p>Address of the host on which the <i>DBMS</i> is running.  This argument may be ignored by some <i>DBMS</i> drivers.</p>
<p><b>Default value:</b> <tt>&quot;&quot;</tt></p>
<p><li><tt>Database</tt></li></p>
<p>Optional argument that can be used to specify a initial database name that is equivalent to use the <tt><a href="#function_MetabaseSetDatabase">MetabaseSetDatabase</a></tt> function.</p>
<p><b>Default value:</b> none</p>
<p><li><tt>Persistent</tt></li></p>
<p>Boolean option that indicates whether the connections to the <i>DBMS</i> should be persistent.  A persistent connection may be reused multiple times from the same application when using the same connection context (user, password, <i>DBMS</i> host, etc.).</p>
<p>Persistent connections are important to minimize <i>DBMS</i> connection overhead that may be avoided, especially when running a PHP as Web server module.</p>
<p><b>Default value:</b> <tt>1</tt></p>
<p><li><tt>AllowNestedTransactions</tt></li></p>
<p>Boolean option that indicates whether the it should be allowed to start a transaction when another transaction is already in progress.</p>
<p><b>Default value:</b> <tt>1</tt></p>
<p><li><tt>DecimalPlaces</tt></li></p>
<p>Integer option that indicates the number of places to the right of the decimal point that should be used to represent values of the decimal data type.  The default value is suitable to represent currency amounts in most applications, but in some markets it is required by law to represent currency values with 3 or more decimal places.</p>
<p><b>Default value:</b> <tt>2</tt></p>
<p><li><tt>Debug</tt></li></p>
<p>Name of a global function that is meant to be called to output debugging information.  If this option is not set or is set an empty string, no debug information is output.</p>
<p><b>Default value:</b> <tt>&quot;&quot;</tt></p>
<p><li><tt>Options</tt></li></p>
<p>Associative array that takes pairs of tag names and values that define the <i>DBMS</i> driver specific options.  Consult the respective driver documentation to learn about the available options.</p>
<p><b>Default value:</b> empty array</p>
<p><li><tt>LOBBufferLength</tt></li></p>
<p>Integer option that indicates the length of the buffer that is used to read data to store in large object fields.</p>
<p><b>Default value:</b> <tt>8000</tt></p>
<p><li><tt>LogLineBreak</tt></li></p>
<p>String option that indicates the characters that will be used to break the lines of the messages that are outputted to the log stream with the <tt><a href="#function_MetabaseDebug">MetabaseDebug</a></tt> function. The default value is suitable for outputting the log lines when using <i>Unix</i> like OS based computers.  For <i>Windows</i> like OS based computers you may want to set this option to <tt>&quot;\r\n&quot;</tt>.</p>
<p><b>Default value:</b> <tt>\n</tt></p>
</ul>
<p>The <tt>$database</tt> argument is a reference to a variable that will hold a unique integer value that works as database access handle.  This handle value should be passed as argument to the other database interface functions.</p>
<p>The <tt>$error</tt> return value contains an error message if this function call did not succeed.  Otherwise it contains an empty string.  This return value may be safely ignored if the function arguments are correctly defined.</p>
<h4>Example</h4>
<ul>
<p><tt>$error=MetabaseSetupDatabase(array(</tt></p>
<ul>
<p><tt>&quot;Type&quot;=&gt;&quot;oci&quot;,</tt><br />
 <tt>&quot;User&quot;=&gt;&quot;oracle_user&quot;,</tt><br />
 <tt>&quot;Password&quot;=&gt;&quot;oracle_user_password&quot;,</tt><br />
 <tt>&quot;Options&quot;=&gt;array(,</tt></p>
<ul>
<p><tt>&quot;SID&quot;=&gt;&quot;dboracle&quot;,</tt><br />
 <tt>&quot;HOME&quot;=&gt;&quot;/home/oracle/u01&quot;,</tt><br />
 <tt>&quot;DBAUser&quot;=&gt;&quot;SYS&quot;,</tt><br />
 <tt>&quot;DBAPassword&quot;=&gt;&quot;change_on_install&quot;</tt></p>
</ul>
<p><tt>),</tt></p>
</ul>
<p><tt>), $database);</tt><br />
 <br />
 <tt>if($error!=&quot;&quot;)</tt><br />
 <tt>{</tt></p>
<ul>
<p><tt>echo &quot;Error while setting database access instance: $error&quot;;</tt><br />
 <tt>exit;</tt></p>
</ul>
<p><tt>}</tt><br />
 <tt>MetabaseSetDatabase($database,&quot;test&quot;);</tt><br />
 <tt>$result=MetabaseQuery($database,&quot;SELECT id,password FROM users WHERE alias='admin'&quot;);</tt><br />
</p>
</ul>
</ul>
<h3><a name="17.2.0"><a name="function_MetabaseSetupDatabaseObject">MetabaseSetupDatabaseObject</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=MetabaseSetupDatabaseObject($arguments, &amp;$db)</tt></p>
<h4>Purpose</h4>
<p>The purpose of this function is the same as the <tt><a href="#function_MetabaseSetupDatabaseObject">MetabaseSetupDatabaseObject</a></tt> function.  The only difference is that the <tt>$database</tt> integer handle argument is replaced by the <tt>$db</tt> object argument that should be used to call the driver class object functions directly instead of calling the <tt>Metabase</tt> API global functions.</p>
<h4>Usage</h4>
<p>This function can not be used under PHP 3 because it takes variable references internally, which is only supported starting from PHP 4.</p>
<p>The <tt>$arguments</tt> argument is an associative array that with the exact same usage as when calling <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$db</tt> argument is a reference to a variable that will hold a driver class object value.  This object value should be used to call the driver object functions directly.</p>
<p>The driver object functions have exactly the same name of the correspondent API global functions, except that they do not have the <tt>Metabase</tt> prefix. If you still need to call the API global functions, you may retrieve the database access integer handle by accessing the <tt>database</tt> driver object variable (<tt>$db-&gt;database</tt>).</p>
<p>The <tt>$error</tt> return value contains an error message if this function call did not succeed.  Otherwise it contains an empty string.  This return value may be safely ignored if the function arguments are correctly defined.</p>
<h4>Example</h4>
<ul>
<p><tt>$error=MetabaseSetupDatabaseObject(array(</tt></p>
<ul>
<p><tt>&quot;Type&quot;=&gt;&quot;oci&quot;,</tt><br />
 <tt>&quot;User&quot;=&gt;&quot;oracle_user&quot;,</tt><br />
 <tt>&quot;Password&quot;=&gt;&quot;oracle_user_password&quot;,</tt><br />
 <tt>&quot;Options&quot;=&gt;array(,</tt></p>
<ul>
<p><tt>&quot;SID&quot;=&gt;&quot;dboracle&quot;,</tt><br />
 <tt>&quot;HOME&quot;=&gt;&quot;/home/oracle/u01&quot;,</tt><br />
 <tt>&quot;DBAUser&quot;=&gt;&quot;SYS&quot;,</tt><br />
 <tt>&quot;DBAPassword&quot;=&gt;&quot;change_on_install&quot;</tt></p>
</ul>
<p><tt>),</tt></p>
</ul>
<p><tt>), $db);</tt><br />
 <br />
 <tt>if($error!=&quot;&quot;)</tt><br />
 <tt>{</tt></p>
<ul>
<p><tt>echo &quot;Error while setting database access instance: $error&quot;;</tt><br />
 <tt>exit;</tt></p>
</ul>
<p><tt>}</tt><br />
 <tt>$db-&gt;SetDatabase(&quot;test&quot;);</tt><br />
 <tt>$result=$db-&gt;Query(&quot;SELECT id,password FROM users WHERE alias='admin'&quot;);</tt><br />
</p>
</ul>
</ul>
<h3><a name="22.2.0"><a name="function_MetabaseParseConnectionArguments">MetabaseParseConnectionArguments</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=MetabaseParseConnectionArguments($connection, $arguments)</tt></p>
<h4>Purpose</h4>
<p>Parse a connection string, as the one that may be passed to the <tt>Connection</tt> argument of the function <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt>, and return array of arguments populated with the arguments that would be passed to that same function if their values were passed separately.</p>
<p>This function can be used to validate a connection string and extract the respective argument values if the string is correctly formatted.</p>
<h4>Usage</h4>
<p>The <tt>$connection</tt> argument is a URL string that defines the database connection arguments as defined for the <tt>Connection</tt> argument for the function <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt>.</p>
<p>The <tt>$arguments</tt> argument is a reference to an array variable that will be populated with the connection arguments. This function does not initialize this array. An already initialized array variable must be passed to the function.</p>
<p>The <tt>$error</tt> return value contains an error message if the connection string is not valid.  Otherwise it contains an empty string.</p>
</ul>
<h3><a name="23.2.0"><a name="function_MetabaseCloseSetup">MetabaseCloseSetup</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>MetabaseCloseSetup($database)</tt></p>
<h4>Purpose</h4>
<p>Release any resources allocated during the access of the specified database instance.  Applications MUST call this function before exit or else incomplete operations may be canceled.</p>
<p>If there is a transaction in progress when this function is called, it is canceled by calling the <tt><a href="#function_MetabaseRollbackTransaction">MetabaseRollbackTransaction</a></tt>. Other <i>DBMS</i> specific resources may be freed depending on the associated driver.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
</ul>
<h3><a name="24.2.0"><a name="function_MetabaseSetDatabase">MetabaseSetDatabase</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$previous_name=MetabaseSetDatabase($database, $name)</tt></p>
<h4>Purpose</h4>
<p>Set the name of the database that is meant to be accessed. This function does not establish a new database connection or closes any previously opened database connection.  It just defines the name of the database that is meant to be access in subsequent operations that necessarily require database access.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name of the database that is meant to be accessed.</p>
<p>The <tt>$previous_name</tt> return value is the name of the database that was set before calling this function.</p>
</ul>
<h3><a name="25.2.0"><a name="function_MetabaseError">MetabaseError</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=MetabaseError($database)</tt></p>
<h4>Purpose</h4>
<p>Retrieve the error message text associated with the last operation that failed.  Some functions may fail but they do not return the reason that makes them to fail.  This function is meant to retrieve a textual description of the failure cause.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$error</tt> return value is the error message text associated with the last failure.</p>
</ul>
<h3><a name="26.2.0"><a name="function_MetabaseSetErrorHandler">MetabaseSetErrorHandler</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$previous_error_handler=MetabaseSetErrorHandler($database, $error_handler)</tt></p>
<h4>Purpose</h4>
<p>Specify a function that is called when an error occurs.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$error_handler</tt> argument is a string with the name of the function that will be called on error.  If an empty string is specified, no handler function is called on error.</p>
<p>The error handler function receives two arguments.  The first argument a reference to the driver class object that triggered the error.  The second argument is a reference to an associative array that provides details about the error that occurred.  These details provide more information than it is returned by the <tt><a href="#function_MetabaseError">MetabaseError</a></tt> function.</p>
<ul>
<p>Here follows the list of currently supported error detail entries:</p>
<p><li><tt>Scope</tt></li></p>
<p>String that indicates the scope of the driver object class within which the error occurred.</p>
<p><li><tt>Message</tt></li></p>
<p>Error message as is returned by the <tt><a href="#function_MetabaseError">MetabaseError</a></tt> function.</p>
</ul>
<p>The <tt>$previous_error_handler</tt> return value is name of the function that was previously defined as error handler.</p>
</ul>
<h3><a name="28.2.0"><a name="function_MetabaseSupport">MetabaseSupport</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$supported=MetabaseSupport($database, $feature)</tt></p>
<h4>Purpose</h4>
<p>Determine if the <i>DBMS</i> driver associated with the given database access handle supports the specified feature.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$feature</tt> argument is the name of the feature that is intended to be queried for support.  Developers should consult the DMBS driver specific documentation to determine which support the features they need to develop their applications.</p>
<p>The name of the features that currently may be queried is as follows:</p>
<ul>
<p><li><tt>AffectedRows</tt></li></p>
<p>Ability to determine the number of table rows that were affected by the last <tt>INSERT</tt>, <tt>UPDATE</tt> or <tt>DELETE</tt> query.</p>
<p><li><tt>AutoIncrement</tt></li></p>
<p>Ability to create and use tables auto-incremented key fields. Support for this feature implies supporting primary keys.</p>
<p><li><tt>Indexes</tt></li></p>
<p>Ability to create indexes on table fields.</p>
<p><li><tt>IndexSorting</tt></li></p>
<p>Ability to specify sorting direction on the creation of table indexes.</p>
<p><li><tt>GetSequenceCurrentValue</tt></li></p>
<p>Ability to retrieve the current value of a sequence. Support for this feature implies supporting sequences.</p>
<p><li><tt>LOBs</tt></li></p>
<p>Has Large OBject table fields to store character or binary data.</p>
<p><li><tt>OmitInsertKey</tt></li></p>
<p>Ability to execute <tt>INSERT</tt> queries omiting the auto-increment key field.</p>
<p><li><tt>OrderByText</tt></li></p>
<p>Ability to order the result of <tt>SELECT</tt> queries by text fields of unspecified length.</p>
<p><li><tt>PatternBuild</tt></li></p>
<p>Ability to build patterns to match text expressions that may include wildcard characters that should be matched literally.</p>
<p><li><tt>PrimaryKey</tt></li></p>
<p>Ability to create tables primary key fields.</p>
<p><li><tt>Replace</tt></li></p>
<p>Ability to execute <tt>REPLACE</tt> queries using the function <tt><a href="#function_MetabaseReplace">MetabaseReplace</a></tt> even if it is done by emulation.</p>
<p><li><tt>SelectRowRanges</tt></li></p>
<p>Ability to restrict the range of result rows that are returned by the <i>DBMS</i> when executing a <tt>SELECT</tt> query.</p>
<p><li><tt>Sequences</tt></li></p>
<p>Ability to create and retrieve sequential values.</p>
<p><li><tt>SummaryFunctions</tt></li></p>
<p>Ability to use summary function on queries such as COUNT, MAX, MIN, AVG, etc..</p>
<p><li><tt>Transactions</tt></li></p>
<p>Ability to start atomic multiple query transactions.</p>
</ul>
</ul>
</ul>
<h2><li><a name="30.1.3">Query execution</a></li></h2>
<ul>
<h3><a name="31.2.0"><a name="function_MetabaseQuery">MetabaseQuery</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$result=MetabaseQuery($database, $query)</tt></p>
<h4>Purpose</h4>
<p>Execute an arbitrary database query statement.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$query</tt> argument is the query statement to be executed.  The values used in the statement should be already in a <i>DBMS</i> specific representation format.</p>
<p>Use the data type conversion functions to convert <i>DBMS</i> independent data values into <i>DBMS</i> specific values to use within this function's query argument.  Alternatively, you may want to use prepared queries to avoid having to compose statements with <i>DBMS</i> specific values.</p>
<p>The <tt>$result</tt> return value determines if this function succeeded.  A value of <tt>0</tt> indicates that the query failed.  For queries that return selected information, the <tt>$result</tt> return value is a handle that should be used access to the query result information.  In this case, the <tt><a href="#function_MetabaseFreeResult">MetabaseFreeResult</a></tt> function should be called when the result information is no longer needed.</p>
</ul>
<h3><a name="32.2.0"><a name="function_MetabaseReplace">MetabaseReplace</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseReplace($database, $table, $fields)</tt></p>
<h4>Purpose</h4>
<p>Execute a <i>SQL</i> <tt>REPLACE</tt> query.  A <tt>REPLACE</tt> query is identical to a <tt>INSERT</tt> query, except that if there is already a row in the table with the same key field values, the <tt>REPLACE</tt> query just updates its values instead of inserting a new row.</p>
<p>The <tt>REPLACE</tt> type of query does not make part of the SQL standards.  Since practically only <i>MySQL</i> implements it natively, this type of query is emulated through this <b>Metabase</b> function for other <i>DBMS</i> using standard types of queries inside a transaction to assure the atomicity of the operation.</p>
<p>Use the <tt><a href="#function_MetabaseSupport">MetabaseSupport</a></tt> function to figure if the current driver class object implements the <tt>REPLACE</tt> query even if it is emulated.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is the name of the table on which the <tt>REPLACE</tt> query will be executed.</p>
<p>The <tt>$fields</tt> argument is an associative array that describes the fields and the values that will be inserted or updated in the specified table.  The indexes of the array are the names of all the fields of the table.  The values of the array are also associative arrays that describe the values and other properties of the table fields.</p>
<ul>
<p>Here follows a list of field properties that need to be specified:</p>
<p><li><tt>Value</tt></li></p>
<p>Value to be assigned to the specified field.  This value may be of specified in database independent type format as this function can perform the necessary datatype conversions.</p>
<p>Default:  this property is required unless the <tt>Null</tt> property is set to <tt>1</tt>.</p>
<p><li><tt>Type</tt></li></p>
<p>Name of the type of the field.  Currently, all types <b>Metabase</b> are supported except for <tt>clob</tt> and <tt>blob</tt>.</p>
<p>Default: <tt>text</tt></p>
<p><li><tt>Null</tt></li></p>
<p>Boolean property that indicates that the value for this field should be set to <tt>NULL</tt>.</p>
<p>The default value for fields missing in <tt>INSERT</tt> queries may be specified the definition of a table.  Often, the default value is already <tt>NULL</tt>, but since the <tt>REPLACE</tt> may be emulated using an <tt>UPDATE</tt> query, make sure that all fields of the table are listed in this function argument array.</p>
<p>Default: <tt>0</tt></p>
<p><li><tt>Key</tt></li></p>
<p>Boolean property that indicates that this field should be handled as a primary key or at least as part of the compound unique index of the table that will determine the row that will updated if it exists or inserted a new row otherwise.</p>
<p>This function will fail if no key field is specified or if the value of a key field is set to <tt>NULL</tt> because fields that are part of unique index they may not be <tt>NULL</tt>.</p>
<p>Default: <tt>0</tt></p>
</ul>
<p>The <tt>$success</tt> return value determines if this function succeeded.  A value of <tt>0</tt> indicates that the query failed.</p>
</ul>
<h3><li><a name="34.2.1">Data type conversion</a></li></h3>
<p><b>Metabase</b> defines a set of base data types that are supported somehow in all <i>DBMS</i> for which there is a driver. However, not all data types are directly supported by each <i>DBMS</i>.</p>
<p>The <i>DBMS</i> drivers are responsible for converting the values of the base datatypes to a representation format that is suitable to emulate their behavior without loss of the values that each type is intended to represent.</p>
<ul>
<h4><a name="35.3.0"><a name="function_MetabaseGetTextFieldValue">MetabaseGetTextFieldValue</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$converted=MetabaseGetTextFieldValue($database, $value)</tt></p>
<h5>Purpose</h5>
<p>Convert a text value into a <i>DBMS</i> specific format that is suitable to compose query statements.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$value</tt> argument is the text string value that is intended to be converted.</p>
<p>The <tt>$converted_value</tt> return value is a text string that already contains any <i>DBMS</i> specific escaped character sequences.</p>
</ul>
<h4><a name="36.3.0"><a name="function_MetabaseGetBooleanFieldValue">MetabaseGetBooleanFieldValue</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$converted_value=MetabaseGetBooleanFieldValue($database, $value)</tt></p>
<h5>Purpose</h5>
<p>Convert a boolean value into a <i>DBMS</i> specific format that is suitable to compose query statements.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$value</tt> argument is the boolean value that is intended to be converted.</p>
<p>The <tt>$converted_value</tt> return value is a text string that represents the given argument value in a <i>DBMS</i> specific format.</p>
</ul>
<h4><a name="37.3.0"><a name="function_MetabaseGetDecimalFieldValue">MetabaseGetDecimalFieldValue</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$converted_value=MetabaseGetDecimalFieldValue($database, $value)</tt></p>
<h5>Purpose</h5>
<p>Convert a decimal value into a <i>DBMS</i> specific format that is suitable to compose query statements.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$value</tt> argument is the decimal value that is intended to be converted.</p>
<p>The <tt>$converted_value</tt> return value is a text string that represents the given argument value in a <i>DBMS</i> specific format.</p>
</ul>
<h4><a name="38.3.0"><a name="function_MetabaseGetFloatFieldValue">MetabaseGetFloatFieldValue</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$converted_value=MetabaseGetFloatFieldValue($database, $value)</tt></p>
<h5>Purpose</h5>
<p>Convert a float value into a <i>DBMS</i> specific format that is suitable to compose query statements.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$value</tt> argument is the float value that is intended to be converted.</p>
<p>The <tt>$converted_value</tt> return value is a text string that represents the given argument value in a <i>DBMS</i> specific format.</p>
</ul>
<h4><a name="39.3.0"><a name="function_MetabaseGetDateFieldValue">MetabaseGetDateFieldValue</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$converted_value=MetabaseGetDateFieldValue($database, $value)</tt></p>
<h5>Purpose</h5>
<p>Convert a date value into a <i>DBMS</i> specific format that is suitable to compose query statements.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$value</tt> argument is the date value that is intended to be converted.  The value should be represent in the <i>ISO 8601</i> format <tt>&quot;YYYY-MM-DD&quot;</tt>.</p>
<p>The <tt>$converted_value</tt> return value is a text string that represents the given argument value in a <i>DBMS</i> specific format.</p>
</ul>
<h4><a name="40.3.0"><a name="function_MetabaseGetTimeFieldValue">MetabaseGetTimeFieldValue</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$converted_value=MetabaseGetTimeFieldValue($database, $value)</tt></p>
<h5>Purpose</h5>
<p>Convert a time value into a <i>DBMS</i> specific format that is suitable to compose query statements.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$value</tt> argument is the time value that is intended to be converted.  The value should be represent in the <i>ISO 8601</i> format <tt>&quot;HH-MI-SS&quot;</tt>.</p>
<p>The <tt>$converted_value</tt> return value is a text string that represents the given argument value in a <i>DBMS</i> specific format.</p>
</ul>
<h4><a name="41.3.0"><a name="function_MetabaseGetTimestampFieldValue">MetabaseGetTimestampFieldValue</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$converted_value=MetabaseGetTimestampFieldValue($database, $value)</tt></p>
<h5>Purpose</h5>
<p>Convert a time stamp value into a <i>DBMS</i> specific format that is suitable to compose query statements.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$value</tt> argument is the time stamp value that is intended to be converted.  The value should be represent in the <i>ISO 8601</i> format <tt>&quot;YYYY-MM-DD HH:MM:SS&quot;</tt>.</p>
<p>The <tt>$converted_value</tt> return value is a text string that represents the given argument value in a <i>DBMS</i> specific format.</p>
</ul>
<h4><a name="42.3.0"><a name="function_MetabaseNow">MetabaseNow</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$timestamp=MetabaseNow()</tt></p>
<h5>Purpose</h5>
<p>Generate a text string that represents the actual date and time on the moment the function is called.  The generated string is in the <i>ISO 8601</i>, so it is suitable to pass to other <b>Metabase</b> functions that take timestamp values.</p>
<h5>Usage</h5>
<p>The <tt>$timestamp</tt> return value is a text string that represents the current date and time.</p>
</ul>
<h4><a name="43.3.0"><a name="function_MetabaseToday">MetabaseToday</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$date=MetabaseToday()</tt></p>
<h5>Purpose</h5>
<p>Generate a text string that represents the actual date on the moment the function is called.  The generated string is in the <i>ISO 8601</i>, so it is suitable to pass to other <b>Metabase</b> functions that take date values.</p>
<h5>Usage</h5>
<p>The <tt>$date</tt> return value is a text string that represents the current date.</p>
</ul>
<h4><a name="44.3.0"><a name="function_MetabaseTime">MetabaseTime</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$time=MetabaseTime()</tt></p>
<h5>Purpose</h5>
<p>Generate a text string that represents the current time on the moment the function is called.  The generated string is in the <i>ISO 8601</i>, so it is suitable to pass to other <b>Metabase</b> functions that take date values.</p>
<h5>Usage</h5>
<p>The <tt>$time</tt> return value is a text string that represents the current time.</p>
</ul>
</ul>
<h3><li><a name="45.2.2">Pattern matching</a></li></h3>
<p>All <i>DBMS</i> provide means to search for patterns in text fields using the <tt>LIKE</tt> operator. It can be used to match a text field value with a pattern that may include wildcard characters.</p>
<p>Patterns may use the character wildcard character <tt>%</tt> to match 0 or more occurrences of any character. The wildcard character <tt>_</tt> may be used to match a single occurence of any character.</p>
<p>The characters <tt>%</tt> and <tt>_</tt> need to be escaped in a special way to be matched literally. Some <i>DBMS</i> also consider other wildcard characters that need to be escaped so they can be used be matched literally.</p>
<p><b>Metabase</b> provides several functions to build patterns and escaping character literals that otherwise would be handled as wildcards.</p>
<ul>
<h4><a name="46.3.0"><a name="function_MetabaseBeginsWith">MetabaseBeginsWith</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$match=MetabaseBeginsWith($database, $value)</tt></p>
<h5>Purpose</h5>
<p>Build a pattern that matches the any text expression that starts with the given text value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$value</tt> argument is the text string value that should match the beginning of the text expression.</p>
<p>The <tt>$match</tt> return value is a text string with an SQL expression to match the given pattern. It starts with the SQL <tt>LIKE</tt> operator.</p>
</ul>
<h4><a name="47.3.0"><a name="function_MetabaseEndsWith">MetabaseEndsWith</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$match=MetabaseEndsWith($database, $value)</tt></p>
<h5>Purpose</h5>
<p>Build a pattern that matches the any text expression that ends with the given text value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$value</tt> argument is the text string value that should match the end of the text expression.</p>
<p>The <tt>$match</tt> return value is a text string with an SQL expression to match the given pattern. It starts with the SQL <tt>LIKE</tt> operator.</p>
</ul>
<h4><a name="48.3.0"><a name="function_MetabaseContains">MetabaseContains</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$match=MetabaseContains($database, $value)</tt></p>
<h5>Purpose</h5>
<p>Build a pattern that matches the any text expression that contains the given text value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$value</tt> argument is the text string value that should match any part of the text expression.</p>
<p>The <tt>$match</tt> return value is a text string with an SQL expression to match the given pattern. It starts with the SQL <tt>LIKE</tt> operator.</p>
</ul>
<h4><a name="49.3.0"><a name="function_MetabaseMatchPattern">MetabaseMatchPattern</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$match=MetabaseMatchPattern($database, $pattern)</tt></p>
<h5>Purpose</h5>
<p>Build a custom pattern that matches a text expression according to the given pattern definition.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$pattern</tt> argument is an array of string values that defines the pattern to match.</p>
<p>The array position 0 and any other values even positions represent strings that should be matched literally. The array position 1 and any other values in odd positions must be strings with the wildcard characters <tt>%</tt> and <tt>_</tt>.</p>
<p>For instance, to match text expressions that start with the literal string <tt>begin</tt>, the pattern array should be defined as: <tt>array( 'begin', '%')</tt>. To match text expressions that end with the literal string <tt>end</tt>, the pattern array should be defined as: <tt>array( '', '%', 'end')</tt>. To match text expressions that contain the literal string <tt>contains</tt>, the pattern array should be defined as: <tt>array( '', '%', 'contains', '%')</tt>.</p>
<p>The <tt>$match</tt> return value is a text string with an SQL expression to match the given pattern. It starts with the SQL <tt>LIKE</tt> operator.</p>
</ul>
</ul>
<h3><li><a name="50.2.3">Auto-incremented keys</a></li></h3>
<p><b>Metabase</b> supports the insertion of table rows with special key fields, known as <i>auto-increment</i> fields. These table fields store automatically generated sequential values.</p>
<p>Although not all <i>DBMS</i> natively support table fields with auto-incremented keys, <b>Metabase</b> provides a <i>DBMS</i> independent set of functions to insert and retrieve this kind of key values.</p>
<p>With certain <i>DBMS</i> that do not support native auto-incremented key fields, the respective <b>Metabase</b> <i>DBMS</i> driver may provide a suitable emulation that makes it work the same way with all <i>DBMS</i>.</p>
<p>If a <i>DBMS</i> driver does not support auto-incremented key fields, not even through emulation, the alternative is to use database sequence objects, if possible. Use the <tt><a href="#function_MetabaseSupport">MetabaseSupport</a></tt> function to determine whether a driver supports either auto-incremented key fields or database sequence objects.</p>
<p>Note that to implement auto-incremented table keys with <i>DBMS</i> that do not support them natively, it is necessary that the table is installed by the function <tt><a href="#function_MetabaseCreateDetailedTable">MetabaseCreateDetailedTable</a></tt> or by <b>Metabase</b> <a href="#database_manager">database schema manager class</a>.</p>
<ul>
<h4><a name="51.3.0"><a name="function_MetabaseGetNextKey">MetabaseGetNextKey</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseGetNextKey($database, $table, $key_sql)</tt></p>
<h5>Purpose</h5>
<p>Retrieve an SQL expression to be used in the place of the value of an auto-incremented key field in SQL <tt>INSERT</tt> queries to insert new rows in a given table.</p>
<h5>Usage</h5>
<p>If the current <i>DBMS</i> supports omitting the auto-increment key field, it is recommended that it is omitted from the <tt>INSERT</tt> query. In that case the function <tt><a href="#function_MetabaseGetNextKey">MetabaseGetNextKey</a></tt> is not necessary.</p>
<p>Use the <tt><a href="#function_MetabaseSupport">MetabaseSupport</a></tt> function to determine whether the current driver class supports omitting the auto-increment key field in <tt>INSERT</tt> queries.</p>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is the name of the table into which a new row will be inserted.</p>
<p>The <tt>$key_sql</tt> argument is a reference to a string variable into which it is returned the SQL expression to be used in the place of the value of an auto-incremented key field in the SQL <tt>INSERT</tt> query.</p>
<p>The <tt>$success</tt> return value determines if this function succeeded.  A value of <tt>0</tt> indicates that it was not possible to retrieve the key SQL expression.</p>
<h5>Example</h5>
<ul>
<p><tt>$success=MetabaseGetNextKey($database, &quot;users&quot;, $key);</tt><br />
 <br />
 <tt>if($success)</tt><br />
 <tt>{</tt></p>
<ul>
<p><tt>$result=MetabaseQuery($database, &quot;INSERT INTO users (id, alias, password) VALUES ( &quot;.$key.&quot;, 'some user', 'some password')&quot;);</tt></p>
</ul>
<p><tt>}</tt></p>
</ul>
</ul>
<h4><a name="54.3.0"><a name="function_MetabaseGetInsertedKey">MetabaseGetInsertedKey</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseGetInsertedKey($database, $table, $key_value)</tt></p>
<h5>Purpose</h5>
<p>Retrieve the value of an auto-incremented key of a row just inserted in a given database table.</p>
<h5>Usage</h5>
<p>This function must be called right after calling <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> that executed the SQL <tt>INSERT</tt> query to insert a row in the table with an auto-incremented key field.</p>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt>  argument is the name of the table into which the new row was inserted.</p>
<p>The <tt>$key_value</tt> is a reference to an integer variable into which it is returned the value of the auto-incremented key value of the row inserted in the specified table.</p>
<p>The <tt>$success</tt> return value determines if this function succeeded.  A value of <tt>0</tt> indicates that it was not possible to retrieve the key value.</p>
</ul>
</ul>
<h3><li><a name="55.2.4">Prepared queries</a></li></h3>
<ul>
<p>Prepared queries are queries that have passed through a pre-parsing process.  They may take less time to run when they are intended to run if they are intended to be run multiple times from the same application.</p>
<p>Prepared queries may have marks that identify the position in the statement where parameter values will be inserted. Insertion positions are marked by the character <tt>?</tt>. Every time a prepared query is executed the insertion marks are substituted by the values defined for the respective parameter.  Parameter values may be changed before each time the query is executed.</p>
<p>Not all <i>DBMS</i> support prepared queries.  For those <i>DBMS</i> that do not support them, prepared queries are emulated by substituting the insertion marks in the query with the parameter values converted to the <i>DBMS</i> specific format using the respective data type conversion functions.</p>
<h4><a name="56.3.0"><a name="function_MetabasePrepareQuery">MetabasePrepareQuery</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$prepared_query=MetabasePrepareQuery($database, $query)</tt></p>
<h5>Purpose</h5>
<p>Create a prepared query.  The specified query is parsed and the resulting data is stored for subsequent execution.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$query</tt> argument is the query statement to be prepared.  <tt>?</tt> character should be used to mark the positions of query parameters in the statement.</p>
<p>The <tt>$prepared_query</tt> return value is a handle that should be passed as argument to the prepared query parameterization and execution functions.  If this function fails the return value is set to <tt>0</tt>.</p>
</ul>
<h4><a name="57.3.0"><a name="function_MetabaseFreePreparedQuery">MetabaseFreePreparedQuery</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseFreePreparedQuery($database, $prepared_query)</tt></p>
<h5>Purpose</h5>
<p>Release resources allocated for the specified prepared query.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully free the resources allocated for the given $prepared_query.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query handle that was not yet freed.</p>
</ul>
<h4><a name="58.3.0"><a name="function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$result=MetabaseExecuteQuery($database, $prepared_query)</tt></p>
<h5>Purpose</h5>
<p>Execute a prepared query statement.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$result</tt> return value determines if this function succeeded.  A value of <tt>0</tt> indicates that there are some undefined parameter values or that the query failed.</p>
<p>For queries that return selected information, the <tt>$result</tt> return value is a handle that should be used access to the query result information.  In this case, the <tt><a href="#function_MetabaseFreeResult">MetabaseFreeResult</a></tt> function should be called when the result information is no longer needed.</p>
</ul>
<h4><a name="59.3.0"><a name="function_MetabaseQuerySet">MetabaseQuerySet</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySet($database, $prepared_query, $parameter, $type, $value, $is_null, $field)</tt></p>
<h5>Purpose</h5>
<p>Set the value of a parameter of a prepared query. Note that this function does not perform any value escaping or data type conversions, like would be done when calling <tt>MetabaseQuerySet&lt;type&gt;</tt> like functions.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$type</tt> argument is designation of the type of the parameter to be set.  The designation of the currently supported types is as follows:</p>
<ul>
<p><li><tt>text</tt></li></p>
<p><li><tt>boolean</tt></li></p>
<p><li><tt>integer</tt></li></p>
<p><li><tt>decimal</tt></li></p>
<p><li><tt>float</tt></li></p>
<p><li><tt>date</tt></li></p>
<p><li><tt>time</tt></li></p>
<p><li><tt>timestamp</tt></li></p>
<p><li><tt>clob</tt></li></p>
<p><li><tt>blob</tt></li></p>
</ul>
<p>The <tt>$value</tt> argument is the value that is meant to be assigned to specified parameter.  The type of the value depends on the <tt>$type</tt> argument.</p>
<p>The <tt>$is_null</tt> argument is a boolean flag that indicates whether whether the parameter is a <tt>NULL</tt>.</p>
<p>The <tt>$field</tt> argument is the name of the field that is meant to be assigned with this parameter value when it is of type <tt>clob</tt> or <tt>blob</tt>.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query and the <tt>$value</tt> argument is a valid value of the specified type.</p>
</ul>
<h4><a name="61.3.0"><a name="function_MetabaseQuerySetNull">MetabaseQuerySetNull</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetNull($database, $prepared_query, $parameter, $type)</tt></p>
<h5>Purpose</h5>
<p>Set the value of a parameter of a prepared query to <tt>NULL</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$type</tt> argument is designation of the type of the parameter to be set.  The designation of the currently supported types is list in the usage of the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query.</p>
</ul>
<h4><a name="62.3.0"><a name="function_MetabaseQuerySetText">MetabaseQuerySetText</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetText($database, $prepared_query, $parameter, $value)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of a prepared query with a text value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$value</tt> argument is a text value that is meant to be assigned to specified parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query and the <tt>$value</tt> argument is a valid text value.</p>
</ul>
<h4><a name="63.3.0"><a name="function_MetabaseQuerySetBoolean">MetabaseQuerySetBoolean</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetBoolean($database, $prepared_query, $parameter, $value)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of a prepared query with a boolean value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$value</tt> argument is a boolean value that is meant to be assigned to specified parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query and the <tt>$value</tt> argument is a valid boolean value.</p>
</ul>
<h4><a name="64.3.0"><a name="function_MetabaseQuerySetInteger">MetabaseQuerySetInteger</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetInteger($database, $prepared_query, $parameter, $value)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of a prepared query with an integer value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$value</tt> argument is an integer value that is meant to be assigned to specified parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query and the <tt>$value</tt> argument is a valid integer value.</p>
</ul>
<h4><a name="65.3.0"><a name="function_MetabaseQuerySetDecimal">MetabaseQuerySetDecimal</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetDecimal($database, $prepared_query, $parameter, $value)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of a prepared query with an decimal value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$value</tt> argument is an decimal value that is meant to be assigned to specified parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query and the <tt>$value</tt> argument is a valid decimal value.</p>
</ul>
<h4><a name="66.3.0"><a name="function_MetabaseQuerySetFloat">MetabaseQuerySetFloat</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetFloat($database, $prepared_query, $parameter, $value)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of a prepared query with a float value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$value</tt> argument is a float value that is meant to be assigned to specified parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query and the <tt>$value</tt> argument is a valid float value.</p>
</ul>
<h4><a name="67.3.0"><a name="function_MetabaseQuerySetDate">MetabaseQuerySetDate</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetDate($database, $prepared_query, $parameter, $value)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of a prepared query with a date value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$value</tt> argument is a date value that is meant to be assigned to specified parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query and the <tt>$value</tt> argument is a valid date value.</p>
</ul>
<h4><a name="68.3.0"><a name="function_MetabaseQuerySetTime">MetabaseQuerySetTime</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetTime($database, $prepared_query, $parameter, $value)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of a prepared query with a date value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$value</tt> argument is a time value that is meant to be assigned to specified parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query and the <tt>$value</tt> argument is a valid time value.</p>
</ul>
<h4><a name="69.3.0"><a name="function_MetabaseQuerySetTimestamp">MetabaseQuerySetTimestamp</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetTimestamp($database, $prepared_query, $parameter, $value)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of a prepared query with a time stamp value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$value</tt> argument is a time stamp value that is meant to be assigned to specified parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query and the <tt>$value</tt> argument is a valid time stamp value.</p>
</ul>
<h4><a name="70.3.0"><a name="function_MetabaseQuerySetCLOB">MetabaseQuerySetCLOB</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetCLOB($database, $prepared_query, $parameter, $value, $field)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of a prepared query with a character large object value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$value</tt> argument is a handle of large object created with <tt><a href="#function_MetabaseCreateLOB">MetabaseCreateLOB</a></tt> function from which it will be read the data value that is meant to be assigned to specified parameter.</p>
<p>The <tt>$field</tt> argument is the name of the field of a <tt>INSERT</tt> or <tt>UPDATE</tt> query to which it will be assigned the value to specified parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query.</p>
</ul>
<h4><a name="71.3.0"><a name="function_MetabaseQuerySetBLOB">MetabaseQuerySetBLOB</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetBLOB($database, $prepared_query, $parameter, $value, $field)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of a prepared query with a binary large object value.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$value</tt> argument is a handle of large object created with <tt><a href="#function_MetabaseCreateLOB">MetabaseCreateLOB</a></tt> function from which it will be read the data value that is meant to be assigned to specified parameter.</p>
<p>The <tt>$field</tt> argument is the name of the field of a <tt>INSERT</tt> or <tt>UPDATE</tt> query to which it will be assigned the value to specified parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query.</p>
</ul>
<h4><a name="72.3.0"><a name="function_MetabaseQuerySetKey">MetabaseQuerySetKey</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseQuerySetKey($database, $prepared_query, $parameter, $table)</tt></p>
<h5>Purpose</h5>
<p>Set a parameter of an <tt>INSERT</tt> prepared query to be bound to the auto-incremented key field of a given table. When the prepared query is executed, <b>Metabase</b> will assign the specified query parameter to the given table auto-incremented key SQL expression as it is returned by the <tt><a href="#function_MetabaseGetNextKey">MetabaseGetNextKey</a></tt> function.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$prepared_query</tt> argument is a handle that was returned by the function <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt>.</p>
<p>The <tt>$parameter</tt> argument is the order number of the parameter in the query statement.  The order number of the first parameter is <tt>1</tt>.</p>
<p>The <tt>$table</tt> argument is the name of the table with the auto-incremented key field to be bound to the specified query parameter.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the specified parameter.  This return value may be safely ignored if the <tt>$prepared_query</tt> argument corresponds to a valid prepared query and the <tt>$table</tt> argument corresponds to a valid table with an auto-incremented key field.</p>
<h5>Example</h5>
<pre>
$prepared_query=MetabasePrepareQuery($database, &quot;INSERT INTO articles (id, title, body) VALUES(?, ?, ?)&quot;);

if($prepared_query)
{
  MetabaseQuerySetKey($database, $prepared_query, 1, &quot;articles&quot;);

  MetabaseQuerySetText($database, $prepared_query, 2, &quot;Some title&quot;);

  MetabaseQuerySetText($database, $prepared_query, 3, &quot;Some body text&quot;);

  if(MetabaseExecuteQuery($database, $prepared_query)

  &amp;&amp; MetabaseGetInsertedKey($database, &quot;articles&quot;, $article_id))

    echo &quot;The article was successfully inserted with identifier&quot;, $article_id, &quot;\n&quot;;

  else

    echo &quot;An error occurred: &quot;, MetabaseError($database), &quot;\n&quot;;
}
</pre>
</ul>
</ul>
<h3><a name="73.2.4"><a name="function_MetabaseSetSelectedRowRange">MetabaseSetSelectedRowRange</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseSetSelectedRowRange($database, $first, $limit)</tt></p>
<h4>Purpose</h4>
<p>Restrict the range of result rows that are returned by the <i>DBMS</i> when executing a <tt>SELECT</tt> query.</p>
<p>The most obvious use for this function is to display query results split into pages with a fixed number of result rows per page to be given by the <tt>$limit</tt> argument.  The <tt>$first</tt> argument would be set to the number of first the record to displayed in each page.  Its value would always be a multiple of the value set to the <tt>$limit</tt> argument starting from <tt>0</tt> for the first page.</p>
<p>This function may also be used to browse individual database records in pages displaying each record with controls to go forward or backwards.  In this case the <tt>$limit</tt> argument would be set to <tt>1</tt> and the <tt>$first</tt> argument value would be increased or decreased depending on whether it would be browsing forward or backwards respectively.</p>
<h4>Usage</h4>
<p>This function should be called right before executing a query using the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> function or creating a prepared query with the <tt><a href="#function_MetabasePrepareQuery">MetabasePrepareQuery</a></tt> function.</p>
<p>After calling these functions the select range values will be reset as if they were never set before.  So, to activate select range restriction, this function has to be called every time before executing a query or creating a prepared query.</p>
<p>The select range may be changed for prepared queries by calling this function before the queries are actually executed with <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt>.  The range values are maintained between subsequent executions of each prepared query with the values that were defined initially or before the last time the prepared query was executed.</p>
<p>The number of rows returned by a query restricted by a range defined by this function is always smaller or equal to the value of the <tt>$limit</tt> argument.  The result row numbers start from <tt>0</tt> but the returned rows correspond to those that would appear in the unrestricted result set displaced by the number specified by the <tt>$first</tt> argument.</p>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$first</tt> argument is number of the first row to be returned when the next <tt>SELECT</tt> query is executed.  Row numbers start from <tt>0</tt>.  If the total number of rows that result from the query is less or equal to the range first row number, the result set will be empty.  The <tt>$first</tt> argument should be equal or greater than <tt>0</tt> or else this function fails.</p>
<p>The <tt>$limit</tt> argument is the maximum number of rows to be returned when the next <tt>SELECT</tt> query is executed.  The result set may return a smaller number of rows if there are not as many rows in the query result set, starting from the row specified by the <tt>$first</tt> argument.  The <tt>$limit</tt> argument should be equal or greater than <tt>1</tt> or else this function fails.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully set the range of rows to be returned by the next <tt>SELECT</tt> query.  This return value may be safely ignored if the respective <tt>DBMS</tt> driver supports selected range rows and <tt>$first</tt> and <tt>$limit</tt> arguments specify valid values.</p>
</ul>
</ul>
<h2><li><a name="74.1.4">Query result handling</a></li></h2>
<ul>
<h3><a name="75.2.0"><a name="function_MetabaseAffectedRows">MetabaseAffectedRows</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseAffectedRows($database, &amp;$affected_rows)</tt></p>
<h4>Purpose</h4>
<p>Determine the number of table rows that were affected by the last <tt>INSERT</tt>, <tt>UPDATE</tt> or <tt>DELETE</tt> query.  Not all <i>DBMS</i> can to determine the number of affected rows by a query.  Use the function <tt><a href="#function_MetabaseSupport">MetabaseSupport</a></tt> to determine whether the <i>DBMS</i> driver has this ability.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$affected_rows</tt> argument is a reference to a variable that will hold the number of affected rows.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully determine the number of affected rows.  This function will always fail if the <i>DBMS</i> driver does not can determine the number of affected rows or the last query was not supposed to affect database table rows.</p>
</ul>
<h3><a name="76.2.0"><a name="function_MetabaseResultIsNull">MetabaseResultIsNull</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$is_null=MetabaseResultIsNull($database, $result, $row, $field)</tt></p>
<h4>Purpose</h4>
<p>Determine whether the value of a query result located in given row and field is a <tt>NULL</tt>.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to check the result value.  Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$field</tt> argument is either the name or the number of the field column from which it is intended to check the result value. Column numbers start from <tt>0</tt>.</p>
<p>The <tt>$is_null</tt> result value is a boolean flag that indicates whether the result value in the given position is a <tt>NULL</tt>.  Applications should not fetch the values of <tt>NULL</tt> result positions.</p>
</ul>
<h3><a name="77.2.0"><a name="function_MetabaseFetchResult">MetabaseFetchResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$value=MetabaseFetchResult($database, $result, $row, $field)</tt></p>
<h4>Purpose</h4>
<p>Fetch the value of a query result located in given row and field.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to fetch the result value.  Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$field</tt> argument is either the name or the number of the field column from which it is intended to fetch the result value. Column numbers start from <tt>0</tt>.</p>
<p>Referencing the result columns by name makes the application code look cleaner. Specifying the column by number runs faster. If you are sure about the order of the columns in the result set, you may want to pass column numbers. One possible compromise is to variable names for readability like this:</p>
<p><tt>$name=0;<br />
$email=1;<br />
$name=MetabaseFetchResult($database, $result,0, $name);<br />
$email=MetabaseFetchResult($database, $result,0, $email);</tt></p>
<p>However, do not use column numbers when you run queries like <tt>SELECT * FROM some_table</tt> because the order that the columns may come is not guaranteed to be always the same, specially after making table alterations.</p>
<p>The <tt>$value</tt> result value is a text string that with the value as it was returned by the <i>DBMS</i>.  Text or integer field result may be used as they are returned, but fields of other types need to be retrieved using data type specific result fetching functions.</p>
</ul>
<h3><a name="78.2.0"><a name="function_MetabaseFetchBooleanResult">MetabaseFetchBooleanResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$value=MetabaseFetchBooleanResult($database, $result, $row, $field)</tt></p>
<h4>Purpose</h4>
<p>Fetch a boolean value of a query result located in given row and field.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to fetch the result boolean value.  Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$field</tt> argument is either the name or the number of the field column from which it is intended to fetch the result boolean value.  Column numbers start from <tt>0</tt>.</p>
<p>The <tt>$value</tt> result value is a text string with the fetched boolean value.</p>
</ul>
<h3><a name="79.2.0"><a name="function_MetabaseFetchDecimalResult">MetabaseFetchDecimalResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$value=MetabaseFetchDecimalResult($database, $result, $row, $field)</tt></p>
<h4>Purpose</h4>
<p>Fetch a decimal value of a query result located in given row and field.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to fetch the result boolean value.  Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$field</tt> argument is either the name or the number of the field column from which it is intended to fetch the result boolean value.  Column numbers start from <tt>0</tt>.</p>
<p>The <tt>$value</tt> result value is a text string that with the fetched decimal value.</p>
</ul>
<h3><a name="80.2.0"><a name="function_MetabaseFetchFloatResult">MetabaseFetchFloatResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$value=MetabaseFetchFloatResult($database, $result, $row, $field)</tt></p>
<h4>Purpose</h4>
<p>Fetch a float value of a query result located in given row and field.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to fetch the result boolean value.  Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$field</tt> argument is either the name or the number of the field column from which it is intended to fetch the result boolean value.  Column numbers start from <tt>0</tt>.</p>
<p>The <tt>$value</tt> result value is a text string with the fetched float.</p>
</ul>
<h3><a name="81.2.0"><a name="function_MetabaseFetchDateResult">MetabaseFetchDateResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$value=MetabaseFetchDateResult($database, $result, $row, $field)</tt></p>
<h4>Purpose</h4>
<p>Fetch a date value of a query result located in given row and field.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to fetch the result date value.  Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$field</tt> argument is either the name or the number of the field column from which it is intended to fetch the result date value.  Column numbers start from <tt>0</tt>.</p>
<p>The <tt>$value</tt> result value is a text string with the date value converted to the normalized ISO format.</p>
</ul>
<h3><a name="82.2.0"><a name="function_MetabaseFetchTimeResult">MetabaseFetchTimeResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$value=MetabaseFetchTimeResult($database, $result, $row, $field)</tt></p>
<h4>Purpose</h4>
<p>Fetch a time value of a query result located in given row and field.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to fetch the result date value.  Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$field</tt> argument is either the name or the number of the field column from which it is intended to fetch the result date value.  Column numbers start from <tt>0</tt>.</p>
<p>The <tt>$value</tt> result value is a text string with the time value converted to the normalized ISO format.</p>
</ul>
<h3><a name="83.2.0"><a name="function_MetabaseFetchTimestampResult">MetabaseFetchTimestampResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$value=MetabaseFetchTimestampResult($database, $result, $row, $field)</tt></p>
<h4>Purpose</h4>
<p>Fetch a time stamp value of a query result located in given row and field.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to fetch the result time stamp value. Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$field</tt> argument is either the name or the number of the field column from which it is intended to fetch the result time stamp value.  Column numbers start from <tt>0</tt>.</p>
<p>The <tt>$value</tt> result value is a text string with the time stamp value converted to the normalized ISO format.</p>
</ul>
<h3><a name="84.2.0"><a name="function_MetabaseFetchCLOBResult">MetabaseFetchCLOBResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$lob_handle=MetabaseFetchCLOBResult($database, $result, $row, $field)</tt></p>
<h4>Purpose</h4>
<p>Fetch the value of a handle to read character large object of a query result located in given row and field.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to fetch the result value.  Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$field</tt> argument is either the name or the number of the field column from which it is intended to fetch the result value. Column numbers start from <tt>0</tt>.</p>
<p>The <tt>$lob_handle</tt> return value is a integer handle that has to be used when retrieving the contents of the specified large object field using the function <tt><a href="#function_MetabaseReadLOB">MetabaseReadLOB</a></tt>.  Each application is responsible for freeing the resources associated with the retrieved large object by calling the function <tt><a href="#function_MetabaseFreeLOB">MetabaseFreeLOB</a></tt>.  If this return value is <tt>0</tt> it means that there was an error.</p>
</ul>
<h3><a name="85.2.0"><a name="function_MetabaseFetchBLOBResult">MetabaseFetchBLOBResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$lob_handle=MetabaseFetchBLOBResult($database, $result, $row, $field)</tt></p>
<h4>Purpose</h4>
<p>Fetch the value of a handle to read binary large object of a query result located in given row and field.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to fetch the result value.  Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$field</tt> argument is either the name or the number of the field column from which it is intended to fetch the result value. Column numbers start from <tt>0</tt>.</p>
<p>The <tt>$lob_handle</tt> return value is a integer handle that has to be used when retrieving the contents of the specified large object field using the function <tt><a href="#function_MetabaseReadLOB">MetabaseReadLOB</a></tt>.  Each application is responsible for freeing the resources associated with the retrieved large object by calling the function <tt><a href="#function_MetabaseFreeLOB">MetabaseFreeLOB</a></tt>.  If this return value is <tt>0</tt> it means that there was an error.</p>
</ul>
<h3><a name="86.2.0"><a name="function_MetabaseEndOfResult">MetabaseEndOfResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$end_of_result=MetabaseEndOfResult($database, $result)</tt></p>
<h4>Purpose</h4>
<p>Determine whether the highest numbered row that was fetched with <tt><a href="#function_MetabaseFetchResult">MetabaseFetchResult</a></tt> like functions is the last row available in the given result set. If no rows have been fetched yet, this function determines whether the result set contains any rows.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$end_of_result</tt> return value indicates whether there are any rows after the highest numbered row that was fetched from the given result set.  If the return value is <tt>0</tt> it means that there is at least one row to be fetched.  If the return value is <tt>1</tt> it means that there no more rows to be fetched.  If the return value is <tt>-1</tt> it means that there was an error.</p>
</ul>
<h3><a name="87.2.0"><a name="function_MetabaseNumberOfRows">MetabaseNumberOfRows</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$rows=MetabaseNumberOfRows($database, $result)</tt></p>
<h4>Purpose</h4>
<p>Count the number of rows returned by the <i>DBMS</i> in a query result.  If the query was executed with the range of result rows restricted by the function <tt><a href="#function_MetabaseSetSelectedRowRange">MetabaseSetSelectedRowRange</a></tt>, the value returned by the <tt><a href="#function_MetabaseNumberOfRows">MetabaseNumberOfRows</a></tt> function never exceeds the range <tt>$limit</tt> value.  The number of rows may be <tt>0</tt> if the <tt>$first</tt> row range value is higher than the the number of rows that the query would return when it is not restricted to a given range.</p>
<p>For performance reasons, avoid using this function with queries that return many rows.  Some <i>DBMS</i> do not provide a means to obtain the total number of rows contained in a result set.  The reason for this is that such <i>DBMS</i> start returning result data as soon as it is found on the database. So, the total number of rows can not be anticipated when the <i>DBMS</i> starts returning result data.</p>
<p>The drivers for these <i>DBMS</i> have to count the number of rows by fetching the whole result data into memory.  Since the applications may still need to fetch the result rows, the data retrieved from the <i>DBMS</i> still has to be hold in memory until the result is freed.  Therefore, using this function may also demand a great amount of memory.</p>
<p>Alternatively, if you really need to know in advance the number of rows that a query will return, you should first run a query that use the <i>SQL</i> <tt>COUNT()</tt> function.</p>
<p>If you just need to know whether all rows in the given result set have been fetched, use the <tt><a href="#function_MetabaseEndOfResult">MetabaseEndOfResult</a></tt> instead.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
</ul>
<h3><a name="88.2.0"><a name="function_MetabaseNumberOfColumns">MetabaseNumberOfColumns</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$columns=MetabaseNumberOfColumns($database, $result)</tt></p>
<h4>Purpose</h4>
<p>Count the number of columns returned by the <i>DBMS</i> in a query result.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$columns</tt> return value indicates the number of columns returned in the specified result set.  Some <i>DBMS</i> may not return any columns when the result set does not contain any rows.  If it is specified an invalid result set, the function will return <tt>-1</tt>.</p>
</ul>
<h3><a name="89.2.0"><a name="function_MetabaseGetColumnNames">MetabaseGetColumnNames</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseGetColumnNames($database, $result, $column_names)</tt></p>
<h4>Purpose</h4>
<p>Retrieve the names of of columns returned by the <i>DBMS</i> in a query result.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$column_names</tt> argument is a reference to an associative array variable that will hold the names of columns.  The indexes of the array are the column names mapped to lower case and the values are the respective numbers of the columns starting from <tt>0</tt>.  Some <i>DBMS</i> may not return any columns when the result set does not contain any rows.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully retrieve the column names associated to the given query result handle.  This return value may be safely ignored if the <tt>$result</tt> argument corresponds to a valid result handle.</p>
</ul>
<h3><a name="90.2.0"><a name="function_MetabaseFreeResult">MetabaseFreeResult</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseFreeResult($database, $result)</tt></p>
<h4>Purpose</h4>
<p></p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully free the resources associated to the given query result handle.  This return value may be safely ignored if the <tt>$result</tt> argument corresponds to a valid result handle that was not already freed.</p>
</ul>
</ul>
<h2><li><a name="91.1.5">Large object data manipulation</a></li></h2>
<p>The data of large objects table fields should not be stored or retrieved all at once because that may require a large amount of memory. The alternative is to retrieve or store data splitting it in blocks of limited length.</p>
<p><b>Metabase</b> provides a set of special purpose classes that are meant to manage the access to blocks of data to be stored or retrieved in large object fields.  The following functions should be used to create and access objects of such classes.</p>
<p>Storing data in large object fields should be done by executing <tt>INSERT</tt> or <tt>UPDATE</tt> prepared queries.  The functions <tt><a href="#function_MetabaseSetQueryCLOB">MetabaseSetQueryCLOB</a></tt> and <tt><a href="#function_MetabaseSetQueryBLOB">MetabaseSetQueryBLOB</a></tt> should be used to specify the large object input stream objects from which the data to be stored will be read when the prepared queries are executed. The function <tt><a href="#function_MetabaseCreateLOB">MetabaseCreateLOB</a></tt> should be used to create input stream objects that define how to read the data to be stored in large object fields.</p>
<p>Data already stored in large object fields should be retrieved by executing <tt>SELECT</tt> queries. The functions <tt><a href="#function_MetabaseFetchCLOBResult">MetabaseFetchCLOBResult</a></tt> and <tt><a href="#function_MetabaseFetchBLOBResult">MetabaseFetchBLOBResult</a></tt> should be used to retrieve the data of the selected large object fields.  These functions return large object handle values that should be used to subsequently read the data using the function <tt><a href="#function_MetabaseReadLOB">MetabaseReadLOB</a></tt>.</p>
<ul>
<h3><a name="92.2.0"><a name="function_MetabaseCreateLOB">MetabaseCreateLOB</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseCreateLOB(&amp;$arguments, &amp;$lob)</tt></p>
<h4>Purpose</h4>
<p>Create a handler object of a specified class with functions to retrieve data from a large object data stream.</p>
<h4>Usage</h4>
<p>The <tt>$arguments</tt> argument is reference to an associative array with parameters to create the handler object. The array indexes are the names of the parameters and the array values are the respective parameter values.</p>
<p>Some parameters are specific of the class of each type of handler object that is created. The following parameters are common to all handler object classes:</p>
<ul>
<p><li><tt>Type</tt></li></p>
<p>Name of the type of the built-in supported class that will be used to create the handler object. There are currently four built-in types of handler object classes: <tt>data</tt>, <tt>resultlob</tt>, <tt>inputfile</tt> and <tt>outputfile</tt>.</p>
<ul>
<p><li>The <tt>data</tt> handler class is the default class. It simply reads data from a given data string.</li></p>
<p><li>The <tt>resultlob</tt> handler class is meant to read data from a large object retrieved from a query result. This class is not used directly by applications.</li></p>
<p><li>The <tt>inputfile</tt> handler class is meant to read data from a file to use in prepared queries with large object field parameters.</li></p>
<p><li>The <tt>outputfile</tt> handler class is meant to write to a file data from result columns with large object fields. The functions to read from this type of large object do not return any data. Instead, the data is just written to the output file with the data retrieved from a specified large object handle.</li></p>
</ul>
<p><li><tt>Class</tt></li></p>
<p>Name of the class of the handler object that will be created if the <tt>Type</tt> argument is not specified. This argument should be used when you need to specify a custom handler class.</p>
<p><li><tt>Database</tt></li></p>
<p>Database connection handler as returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt>.  This is an option argument needed by some handler classes like <tt>resultlob</tt>.</p>
<p><li><tt>Error</tt></li></p>
<p>Optional error entry that will hold the error message returned by this function when it fails.</p>
</ul>
<p>The following argument is specific of the <tt>data</tt> handler class:</p>
<ul>
<p><li><tt>Data</tt></li></p>
<p>String of data that will be returned by the class when it requested with the <tt><a href="#function_MetabaseReadLOB">MetabaseReadLOB</a></tt> function.</p>
</ul>
<p>The following argument is specific of the <tt>resultlob</tt> handler class:</p>
<ul>
<p><li><tt>ResultLOB</tt></li></p>
<p>Integer handle value of a large object result row field.</p>
</ul>
<p>The following arguments are specific of the <tt>inputfile</tt> handler class:</p>
<ul>
<p><li><tt>File</tt></li></p>
<p>Integer handle value of a file already opened for reading.</p>
<p><li><tt>FileName</tt></li></p>
<p>Name of a file to be opened for reading if the <tt>File</tt> argument is not specified.</p>
</ul>
<p>The following arguments are specific of the <tt>outputfile</tt> handler class:</p>
<ul>
<p><li><tt>File</tt></li></p>
<p>Integer handle value of a file already opened for writing.</p>
<p><li><tt>FileName</tt></li></p>
<p>Name of a file to be opened for writing if the <tt>File</tt> argument is not specified.</p>
<p><li><tt>BufferLength</tt></li></p>
<p>Integer value that specifies the length of a buffer that will be used to read from the specified large object.</p>
<p><li><tt>LOB</tt></li></p>
<p>Integer handle value that specifies a large object from which the data to be stored in the output file will be written.</p>
<p><li><tt>Result</tt></li></p>
<p>Integer handle value as returned by the function <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> that specifies the result set that contains the large object value to be retrieved.  If the <tt>LOB</tt> argument is specified, this argument is ignored.</p>
<p><li><tt>Row</tt></li></p>
<p>Integer value that specifies the number of the row of the result set that contains the large object value to be retrieved. If the <tt>LOB</tt> argument is specified, this argument is ignored.</p>
<p><li><tt>Field</tt></li></p>
<p>Integer or string value that specifies the number or the name of the column of the result set that contains the large object value to be retrieved. If the <tt>LOB</tt> argument is specified, this argument is ignored.</p>
<p><li><tt>Binary</tt></li></p>
<p>Boolean value that specifies whether the large object column to be retrieved is of binary type (<tt>blob</tt>) or otherwise is of character type (<tt>clob</tt>). If the <tt>LOB</tt> argument is specified, this argument is ignored.</p>
</ul>
<p>The <tt>$lob</tt> argument is a reference to a variable that will hold an integer handle value that should be passed as argument in subsequent calls to functions that retrieve data from the large object input stream.</p>
<p>The <tt>$success</tt> return value indicates whether the function was able to successfully create the large object handler object.</p>
</ul>
<h3><a name="99.2.0"><a name="function_MetabaseReadLOB">MetabaseReadLOB</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$read_length=MetabaseReadLOB($lob, &amp;$data, $length)</tt></p>
<h4>Purpose</h4>
<p>Read data from large object input stream.</p>
<h4>Usage</h4>
<p>The <tt>$lob</tt> argument is a integer handle value that is returned by the <tt><a href="#function_MetabaseCreateLOB">MetabaseCreateLOB</a></tt> function.</p>
<p>The <tt>$data</tt> argument is a reference to a variable that will hold data to be read from the large object input stream.</p>
<p>The <tt>$length</tt> argument is a integer value that indicates the largest amount of data to be read from the large object input stream.</p>
<p>The <tt>$read_length</tt> return value indicates the effective number of bytes read from the large object input stream.</p>
<p>If this function succeeded, the return value may range from <tt>0</tt> up to the value of the <tt>$length</tt> argument. Use the function <tt><a href="#function_MetabaseEndOfLOB">MetabaseEndOfLOB</a></tt> to determine if there is still more data to be retrieved.</p>
<p>If this function fails, the return value is <tt>-1</tt>. Use the function <tt><a href="#function_MetabaseLOBError">MetabaseLOBError</a></tt> to retrieve the associated error message.</p>
</ul>
<h3><a name="100.2.0"><a name="function_MetabaseEndOfLOB">MetabaseEndOfLOB</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$end_of_lob=MetabaseEndLOB($lob)</tt></p>
<h4>Purpose</h4>
<p>Determine whether it was reached the end of the large object and therefore there is no more data to be read for the its input stream.</p>
<h4>Usage</h4>
<p>The <tt>$lob</tt> argument is a integer handle value that is returned by the <tt><a href="#function_MetabaseCreateLOB">MetabaseCreateLOB</a></tt> function.</p>
<p>The <tt>$end_of_lob</tt> return value is a boolean flag that indicates whether it was reached the end of the large object input stream.</p>
</ul>
<h3><a name="101.2.0"><a name="function_MetabaseDestroyLOB">MetabaseDestroyLOB</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>MetabaseDestroyLOB($lob)</tt></p>
<h4>Purpose</h4>
<p>Free any resources allocated during the lifetime of the large object handler object.</p>
<h4>Usage</h4>
<p>The <tt>$lob</tt> argument is a integer handle value that is returned by the <tt><a href="#function_MetabaseCreateLOB">MetabaseCreateLOB</a></tt> function.</p>
</ul>
<h3><a name="102.2.0"><a name="function_MetabaseLOBError">MetabaseLOBError</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=MetabaseLOBError($lob)</tt></p>
<h4>Purpose</h4>
<p>Retrieve the error message text associated with the last operation on the large object input stream that failed.</p>
<h4>Usage</h4>
<p>The <tt>$lob</tt> argument is a integer handle value that is returned by the <tt><a href="#function_MetabaseCreateLOB">MetabaseCreateLOB</a></tt> function.</p>
<p>The <tt>$error</tt> return value is the error message string.</p>
</ul>
<h3><a name="103.2.0"><a name="function_MetabaseEndOfLOB">MetabaseEndOfLOB</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$end_of_lob=MetabaseEndLOB($lob)</tt></p>
<h4>Purpose</h4>
<p>Determine whether it was reached the end of the large object and therefore there is no more data to be read for the its input stream.</p>
<h4>Usage</h4>
<p>The <tt>$lob</tt> argument is a integer handle value that is returned by the <tt><a href="#function_MetabaseCreateLOB">MetabaseCreateLOB</a></tt> function.</p>
<p>The <tt>$end_of_lob</tt> return value is a boolean flag that indicates whether it was reached the end of the large object input stream.</p>
</ul>
<h3><a name="104.2.0"><a name="function_MetabaseDestroyLOB">MetabaseDestroyLOB</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>MetabaseDestroyLOB($lob)</tt></p>
<h4>Purpose</h4>
<p>Free any resources allocated during the lifetime of the large object handler object.</p>
<h4>Usage</h4>
<p>The <tt>$lob</tt> argument is a integer handle value that is returned by the <tt><a href="#function_MetabaseCreateLOB">MetabaseCreateLOB</a></tt> function.</p>
</ul>
</ul>
<h2><li><a name="105.1.6">Query result set bulk data fetching</a></li></h2>
<ul>
<p>The most common use of database applications is to retrieve information that is stored table rows.  The process to retrieve data from a database is repetitive:  execute a query, iterate over the result set and free it.</p>
<p>To simplify this repetitive process, <b>Metabase</b> provides an additional set of functions that is meant to reduce the number of calls to the <i>API</i> when retrieving result set data in the most common ways.</p>
<p>There are two main types of functions that are provided for retrieving data in bulk with a single call.  The simplest type of functions just retrieves the data into a given variable from the result set of an already executed query and then frees the result set.</p>
<p>The second type of functions wraps around the first functions and besides that also executes a given immediate query before retrieving the result set data.</p>
<p>The first type of functions is more appropriate to use with prepared queries because the second type of functions performs the same actions and also execute immediate queries.</p>
<p>These types of functions retrieve data in four different manners:</p>
<ul>
<p><li>Fetch just the first field value from the first result set row.</li></p>
<p><li>Fetch just the first result set row.</li></p>
<p><li>Fetch the first field value from all rows of the result set.</li></p>
<p><li>Fetch all rows of the result set.</li></p>
</ul>
<p>Besides these main types of functions there is also a function that fetches data from a given row of a result set and another function that is meant to define the data types that should be associated to each result set column, so that the necessary datatype conversions are already performed before returning data.</p>
<h3><a name="107.2.0"><a name="function_MetabaseSetResultTypes">MetabaseSetResultTypes</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseSetResultTypes($database, $result, &amp;$types)</tt></p>
<h4>Purpose</h4>
<p>Define the list of types to be associated with the columns of a given result set.</p>
<p>This function may be called before invoking <tt><a href="#function_MetabaseFetchResultArray">MetabaseFetchResultArray</a></tt>, <tt><a href="#function_MetabaseFetchResultField">MetabaseFetchResultField</a></tt>, <tt><a href="#function_MetabaseFetchResultRow">MetabaseFetchResultRow</a></tt>, <tt><a href="#function_MetabaseFetchResultColumn">MetabaseFetchResultColumn</a></tt> and <tt><a href="#function_MetabaseFetchResultAll">MetabaseFetchResultAll</a></tt> so that the necessary data type conversions are performed on the data to be retrieved by them.  If this function is not called, the type of all result set columns is assumed to be text, thus leading to not perform any conversions.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$types</tt> argument is an array variable that lists the data types to be expected in the result set columns. If the array is associative, the names used in the keys will be used as indexes of the result arrays returned by the functions <tt><a href="#function_MetabaseFetchResultRow">MetabaseFetchResultRow</a></tt> and <tt><a href="#function_MetabaseFetchResultAll">MetabaseFetchResultAll</a></tt>. If this array contains less types than the number of columns that are returned in the result set, the remaining columns are assumed to be of the type <tt>text</tt>. Currently, the types <tt>clob</tt> and <tt>blob</tt> are not fully supported.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in associating the types list to the given result set.  This return value may be safely ignored if the function arguments are correctly defined.</p>
</ul>
<h3><a name="108.2.0"><a name="function_MetabaseFetchResultArray">MetabaseFetchResultArray</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseFetchResultArray($database, $result, &amp;$array, $row)</tt></p>
<h4>Purpose</h4>
<p>Fetch a specified result set row into a given array variable.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions.</p>
<p>The <tt>$array</tt> argument is a reference to an array variable into which the specified result set row values are fetched.  The array positions are filled according to the position of the result set columns starting from <tt>0</tt>.  Columns with <tt>NULL</tt> values are not assigned.</p>
<p>The <tt>$row</tt> argument is the number of the row from which it is intended to fetch the result set row.  Row numbers start from <tt>0</tt>.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the given row result set data.</p>
</ul>
<h3><a name="109.2.0"><a name="function_MetabaseFetchResultField">MetabaseFetchResultField</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseFetchResultField($database, $result, &amp;$field)</tt></p>
<h4>Purpose</h4>
<p>Fetch the value from the first column of the first row of the specified result set into a given variable and then frees the result set.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions. The specified result set is always freed even if retrieving the field value fails for any reason.  This function assumes that no data was already retrieved from the result set or else it may fail stating the result set is empty.</p>
<p>The <tt>$field</tt> argument is a reference to a variable into which the specified result set field is fetched.  If it is <tt>NULL</tt> this variable is unset.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the result set field value.</p>
</ul>
<h3><a name="110.2.0"><a name="function_MetabaseFetchResultRow">MetabaseFetchResultRow</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseFetchResultRow($database, $result, &amp;$row)</tt></p>
<h4>Purpose</h4>
<p>Fetch the first row of the specified result set row into a given array variable and then frees the result set.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions. The specified result set is always freed even if retrieving the row values fails for any reason.  This function assumes that no data was already retrieved from the result set or else it may fail stating the result set is empty.</p>
<p>The types set with the function <tt><a href="#function_MetabaseSetResultTypes">MetabaseSetResultTypes</a></tt> affect the results returned by this function. If the types array is associative, the results row array is also associative using the same indexes from the types array.</p>
<p>The <tt>$row</tt> argument is a reference to an array variable into which the specified result set row values are fetched.  The array positions are filled according to the position of the result set columns starting from <tt>0</tt>.  Columns with <tt>NULL</tt> values are not assigned.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the result set row data.</p>
</ul>
<h3><a name="111.2.0"><a name="function_MetabaseFetchResultColumn">MetabaseFetchResultColumn</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseFetchResultColumn($database, $result, &amp;$column)</tt></p>
<h4>Purpose</h4>
<p>Fetch the value from the first column of all the rows of the specified result set into a given array variable and then frees the result set.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions. The specified result set is always freed even if retrieving the column values fails for any reason.  This function assumes that no data was already retrieved from the result set or else it may not return any data.</p>
<p>The <tt>$column</tt> argument is a reference to an array variable into which the specified result set column is fetched. The rows on which the first column is <tt>NULL</tt> are ignored.  Therefore, do not rely on the count of entries of the array variable to assume that it is the number of rows in the result set.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the result set column data.</p>
</ul>
<h3><a name="112.2.0"><a name="function_MetabaseFetchResultAll">MetabaseFetchResultAll</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseFetchResultAll($database, $result, &amp;$all)</tt></p>
<h4>Purpose</h4>
<p>Fetch all rows of the specified result set row into a given two dimension array variable and then frees the result set.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$result</tt> argument is a handle for the query result set that was returned by either the <tt><a href="#function_MetabaseQuery">MetabaseQuery</a></tt> or <tt><a href="#function_MetabaseExecuteQuery">MetabaseExecuteQuery</a></tt> functions. The specified result set is always freed even if retrieving the its values fails for any reason.  This function assumes that no data was already retrieved from the result set or else it may not return any data.</p>
<p>The <tt>$all</tt> argument is a reference to a two dimension array variable into which the specified result set rows and column values are fetched.  The array positions are filled according to the position of the result set columns and rows starting from <tt>0</tt>.  Columns with <tt>NULL</tt> values are not assigned.</p>
<p>The types set with the function <tt><a href="#function_MetabaseSetResultTypes">MetabaseSetResultTypes</a></tt> affect the results returned by this function. If the types array is associative, the results row array is also associative using the same indexes from the types array.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the result set row data.</p>
</ul>
<h3><a name="113.2.0"><a name="function_MetabaseQueryField">MetabaseQueryField</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseQueryField($database, $query , &amp;$field, $type)</tt></p>
<h4>Purpose</h4>
<p>Execute the specified query, fetch the value from the first column of the first row of the result set into a given variable and then frees the result set.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$query</tt> argument is the <tt>SELECT</tt> query statement to be executed.</p>
<p>The <tt>$field</tt> argument is a reference to a variable into which the result set field is fetched.  If it is <tt>NULL</tt> this variable is unset.</p>
<p><tt>$type</tt> is an optional argument that specifies the expected datatype of the result set field, so that an eventual conversion may be performed.  The default datatype is <tt>text</tt>, meaning that no conversion is performed.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in executing the query and retrieving the result set field value.</p>
</ul>
<h3><a name="114.2.0"><a name="function_MetabaseQueryRow">MetabaseQueryRow</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseQueryRow($database, $query, &amp;$row, $types)</tt></p>
<h4>Purpose</h4>
<p>Execute the specified query, fetch the first row of the result set row into a given array variable and then frees the result set.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$query</tt> argument is the <tt>SELECT</tt> query statement to be executed.</p>
<p>The <tt>$row</tt> argument is a reference to an array variable into which the result set row values are fetched.  The array positions are filled according to the position of the result set columns starting from <tt>0</tt>.  Columns with <tt>NULL</tt> values are not assigned.</p>
<p><tt>$types</tt> is an optional array argument that specifies a list of expected datatypes of the result set columns, so that the eventual conversions may be performed.  The default list of datatypes is empty, meaning that no conversion is performed.</p>
<p>If the types array is associative, the results row array is also associative using the same indexes from the types array.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in executing the query and retrieving the result set row data.</p>
</ul>
<h3><a name="115.2.0"><a name="function_MetabaseQueryColumn">MetabaseQueryColumn</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseQueryColumn($database, $query, &amp;$column, $type)</tt></p>
<h4>Purpose</h4>
<p>Execute the specified query, fetch the value from the first column of all the rows of the result set into a given array variable and then frees the result set.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$query</tt> argument is the <tt>SELECT</tt> query statement to be executed.</p>
<p>The <tt>$column</tt> argument is a reference to an array variable into which the result set column is fetched.  The rows on which the first column is <tt>NULL</tt> are ignored. Therefore, do not rely on the count of entries of the array variable to assume that it is the number of rows in the result set.</p>
<p><tt>$type</tt> is an optional argument that specifies the expected datatype of the result set column, so that an eventual conversion may be performed.  The default datatype is <tt>text</tt>, meaning that no conversion is performed.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in executing the query and retrieving the result set column data.</p>
</ul>
<h3><a name="116.2.0"><a name="function_MetabaseQueryAll">MetabaseQueryAll</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseQueryAll($database, $query, &amp;$all, $types)</tt></p>
<h4>Purpose</h4>
<p>Execute the specified query, fetch all rows of the result set row into a given two dimension array variable and then frees the result set.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$query</tt> argument is the <tt>SELECT</tt> query statement to be executed.</p>
<p>The <tt>$all</tt> argument is a reference to a two dimension array variable into which the result set rows and column values are fetched.  The array positions are filled according to the position of the result set columns and rows starting from <tt>0</tt>.  Columns with <tt>NULL</tt> values are not assigned.</p>
<p><tt>$types</tt> is an optional array argument that specifies a list of expected datatypes of the result set columns, so that the eventual conversions may be performed.  The default list of datatypes is empty, meaning that no conversion is performed.</p>
<p>If the types array is associative, the results array for each row is also associative using the same indexes from the types array.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in executing the query and retrieving the result set data.</p>
</ul>
</ul>
<h2><li><a name="117.1.7">Transaction management</a></li></h2>
<ul>
<p>A transaction is a set of operations that are executed atomically by the <i>DBMS</i>.  The operations that are executed during a transaction by a database user are not affected by other operations being executed at the same time during the access of other users.</p>
<p>In practice this means that the <i>DBMS</i> behaves as if the database is being accessed by one user at a time while a transaction takes place.  The <i>DBMS</i> may set implicit locks that prevent simultaneous accesses to affects the same data.</p>
<p>A transaction is ended by a commit command or by a rollback command.  The commit command tells the <i>DBMS</i> to make definite the changes done on the database.  The rollback command tells the <i>DBMS</i> to cancel the changes done on the database since the transaction begun.</p>
<p>If for some reason a transaction is not completed before a database connection is terminated either ending the application normally or abnormally, the <i>DBMS</i> execute an implicit rollback operation.  This includes situations when the application is terminated by the operating system or the computer where the application or the <i>DBMS</i> is running is shutdown by a power interruption.</p>
<p>An application script may be terminated without ending a transaction.  The function <tt><a href="#function_MetabaseCloseSetup">MetabaseCloseSetup</a></tt> ends an uncommitted transaction that may be in progress when it is called, but if a script exits without calling this function, for instance due to a syntax error, the transaction could be left pending until the application process ends.</p>
<p>Since <b>Metabase</b> supports persistent database connections, there would be a chance that an uncommitted transaction be left pending until the Web server process is terminated, therefore holding implicit database access locks.</p>
<p>To prevent this situation, <b>Metabase</b> implicitly registers a shutdown handler function with PHP that assures that any pending transactions are canceled before the script exits.</p>
<p>By default, <b>Metabase</b> allows to start nested transactions, i.e. a transaction started while another is already in progress. In reality, when a second transaction is started, <b>Metabase</b> just continues the current transaction.</p>
<p>A nested transaction is only finished when the first transaction is ended either by committing or rolling back the transaction. If an inner transaction is rolled back, the first transaction must be also rolled back. Otherwise, <b>Metabase</b> will fail in error, as this situation is a result of an application inconsistency bug.</p>
<p>Nested transactions may be disallowed by using the database setup option <tt>AllowNestedTransactions</tt>.</p>
<p>Not all <i>DBMS</i> support transactions.  Use the function <tt><a href="#function_MetabaseSupport">MetabaseSupport</a></tt> to determine whether the <i>DBMS</i> driver support transactions.</p>
<h3><a name="118.2.0"><a name="function_MetabaseAutoCommitTransactions">MetabaseAutoCommitTransactions</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseAutoCommitTransactions($database, $auto_commit)</tt></p>
<h4>Purpose</h4>
<p>Define whether database changes done on the database be automatically committed.  This function may also implicitly start or end a transaction.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$auto_commit</tt> argument is a boolean flag that indicates whether the database changes should be committed right after executing every query statement.  If this argument is <tt>0</tt> a transaction implicitly started.  Otherwise, if a transaction is in progress it is ended by committing any database changes that were pending.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in either starting a transaction or committing any changes and ending a transaction in progress.</p>
</ul>
<h3><a name="119.2.0"><a name="function_MetabaseCommitTransaction">MetabaseCommitTransaction</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseCommitTransaction($database)</tt></p>
<h4>Purpose</h4>
<p>Commit the database changes done during a transaction that is in progress.  This function may only be called when auto-committing is disabled, otherwise it will fail. Therefore, a new transaction is implicitly started after committing the pending changes.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in committing the database changes and starting a new transaction.</p>
</ul>
<h3><a name="120.2.0"><a name="function_MetabaseRollbackTransaction">MetabaseRollbackTransaction</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=MetabaseRollbackTransaction($database)</tt></p>
<h4>Purpose</h4>
<p>Cancel any database changes done during a transaction that is in progress.  This function may only be called when auto-committing is disabled, otherwise it will fail. Therefore, a new transaction is implicitly started after canceling the pending changes.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in canceling the database changes and starting a new transaction.</p>
</ul>
</ul>
<h2><li><a name="121.1.8">Database schema objects management</a></li></h2>
<ul>
<h3><a name="122.2.0">Databases</a></h3>
<ul>
<h4><a name="123.3.0"><a name="function_MetabaseCreateDatabase">MetabaseCreateDatabase</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseCreateDatabase($database, $name)</tt></p>
<h5>Purpose</h5>
<p>Create a database space within which may be created database objects like tables, indexes and sequences.  The implementation of this function is highly <i>DBMS</i> specific and may require special permissions to run successfully.  Consult the documentation or the <i>DBMS</i> drivers that you use to be aware of eventual configuration requirements.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name of the database that is intended to be created.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in creating the new database.</p>
</ul>
<h4><a name="124.3.0"><a name="function_MetabaseDropDatabase">MetabaseDropDatabase</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseDropDatabase($database, $name)</tt></p>
<h5>Purpose</h5>
<p>Drop an existing database space.  The implementation of this function is highly <i>DBMS</i> specific and may require special permissions to run successfully.  Consult the documentation or the <i>DBMS</i> drivers that you use to be aware of eventual configuration requirements.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name of the database that is intended to be dropped.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in dropping the specified database.</p>
</ul>
</ul>
<h3><a name="125.2.0">Tables</a></h3>
<ul>
<h4><a name="126.3.0"><a name="function_MetabaseGetTextFieldTypeDeclaration">MetabaseGetTextFieldTypeDeclaration</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$declaration=MetabaseGetTextFieldTypeDeclaration($database, $name, &amp;$field)</tt></p>
<h5>Purpose</h5>
<p>Obtain <i>DBMS</i> specific <i>SQL</i> code portion needed to declare a text type field to be used in statements like <tt>CREATE TABLE</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name the field to be declared.</p>
<p>The <tt>$field</tt> argument is an associative array with the name of the properties of the field being declared as array indexes.  Currently, the types of supported field properties are as follows:</p>
<ul>
<p><li><tt>length</tt></li></p>
<p>Integer value that determines the maximum length of the text field.  If this argument is missing the field should be declared to have the longest length allowed by the DBMS.</p>
<p><li><tt>default</tt></li></p>
<p>Text value to be used as default for this field.</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag that indicates whether this field is constrained to not be set to <tt>NULL</tt>.</p>
</ul>
<p>The <tt>$declaration</tt> return value is the <i>DBMS</i> specific <i>SQL</i> code portion that should be used to declare the specified field.</p>
</ul>
<h4><a name="128.3.0"><a name="function_MetabaseGetBooleanFieldTypeDeclaration">MetabaseGetBooleanFieldTypeDeclaration</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$declaration=MetabaseGetBooleanFieldTypeDeclaration($database, $name, &amp;$field)</tt></p>
<h5>Purpose</h5>
<p>Obtain <i>DBMS</i> specific <i>SQL</i> code portion needed to declare a boolean type field to be used in statements like <tt>CREATE TABLE</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name the field to be declared.</p>
<p>The <tt>$field</tt> argument is an associative array with the name of the properties of the field being declared as array indexes.  Currently, the types of supported field properties are as follows:</p>
<ul>
<p><li><tt>default</tt></li></p>
<p>Boolean value to be used as default for this field.</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag that indicates whether this field is constrained to not be set to <tt>NULL</tt>.</p>
</ul>
<p>The <tt>$declaration</tt> return value is the <i>DBMS</i> specific <i>SQL</i> code portion that should be used to declare the specified field.</p>
</ul>
<h4><a name="130.3.0"><a name="function_MetabaseGetIntegerFieldTypeDeclaration">MetabaseGetIntegerFieldTypeDeclaration</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$declaration=MetabaseGetIntegerFieldTypeDeclaration($database, $name, &amp;$field)</tt></p>
<h5>Purpose</h5>
<p>Obtain <i>DBMS</i> specific <i>SQL</i> code portion needed to declare an integer type field to be used in statements like <tt>CREATE TABLE</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name the field to be declared.</p>
<p>The <tt>$field</tt> argument is an associative array with the name of the properties of the field being declared as array indexes.  Currently, the types of supported field properties are as follows:</p>
<ul>
<p><li><tt>unsigned</tt></li></p>
<p>Boolean flag that indicates whether the field should be declared as unsigned integer if possible.</p>
<p><li><tt>default</tt></li></p>
<p>Integer value to be used as default for this field.</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag that indicates whether this field is constrained to not be set to <tt>NULL</tt>.</p>
</ul>
<p>The <tt>$declaration</tt> return value is the <i>DBMS</i> specific <i>SQL</i> code portion that should be used to declare the specified field.</p>
</ul>
<h4><a name="132.3.0"><a name="function_MetabaseGetDecimalFieldTypeDeclaration">MetabaseGetDecimalFieldTypeDeclaration</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$declaration=MetabaseGetDecimalFieldTypeDeclaration($database, $name, &amp;$field)</tt></p>
<h5>Purpose</h5>
<p>Obtain <i>DBMS</i> specific <i>SQL</i> code portion needed to declare a decimal type field to be used in statements like <tt>CREATE TABLE</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name the field to be declared.</p>
<p>The <tt>$field</tt> argument is an associative array with the name of the properties of the field being declared as array indexes.  Currently, the types of supported field properties are as follows:</p>
<ul>
<p><li><tt>default</tt></li></p>
<p>Integer value to be used as default for this field.</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag that indicates whether this field is constrained to not be set to <tt>NULL</tt>.</p>
</ul>
<p>The <tt>$declaration</tt> return value is the <i>DBMS</i> specific <i>SQL</i> code portion that should be used to declare the specified field.</p>
</ul>
<h4><a name="134.3.0"><a name="function_MetabaseGetFloatFieldTypeDeclaration">MetabaseGetFloatFieldTypeDeclaration</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$declaration=MetabaseGetFloatFieldTypeDeclaration($database, $name, &amp;$field)</tt></p>
<h5>Purpose</h5>
<p>Obtain <i>DBMS</i> specific <i>SQL</i> code portion needed to declare a float type field to be used in statements like <tt>CREATE TABLE</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name the field to be declared.</p>
<p>The <tt>$field</tt> argument is an associative array with the name of the properties of the field being declared as array indexes.  Currently, the types of supported field properties are as follows:</p>
<ul>
<p><li><tt>default</tt></li></p>
<p>Integer value to be used as default for this field.</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag that indicates whether this field is constrained to not be set to <tt>NULL</tt>.</p>
</ul>
<p>The <tt>$declaration</tt> return value is the <i>DBMS</i> specific <i>SQL</i> code portion that should be used to declare the specified field.</p>
</ul>
<h4><a name="136.3.0"><a name="function_MetabaseGetDateFieldTypeDeclaration">MetabaseGetDateFieldTypeDeclaration</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$declaration=MetabaseGetDateFieldTypeDeclaration($database, $name, &amp;$field)</tt></p>
<h5>Purpose</h5>
<p>Obtain <i>DBMS</i> specific <i>SQL</i> code portion needed to declare a date type field to be used in statements like <tt>CREATE TABLE</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name the field to be declared.</p>
<p>The <tt>$field</tt> argument is an associative array with the name of the properties of the field being declared as array indexes.  Currently, the types of supported field properties are as follows:</p>
<ul>
<p><li><tt>default</tt></li></p>
<p>Date value to be used as default for this field.</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag that indicates whether this field is constrained to not be set to <tt>NULL</tt>.</p>
</ul>
<p>The <tt>$declaration</tt> return value is the <i>DBMS</i> specific <i>SQL</i> code portion that should be used to declare the specified field.</p>
</ul>
<h4><a name="138.3.0"><a name="function_MetabaseGetTimeFieldTypeDeclaration">MetabaseGetTimeFieldTypeDeclaration</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$declaration=MetabaseGetTimeFieldTypeDeclaration($database, $name, &amp;$field)</tt></p>
<h5>Purpose</h5>
<p>Obtain <i>DBMS</i> specific <i>SQL</i> code portion needed to declare an time type field to be used in statements like <tt>CREATE TABLE</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name the field to be declared.</p>
<p>The <tt>$field</tt> argument is an associative array with the name of the properties of the field being declared as array indexes.  Currently, the types of supported field properties are as follows:</p>
<ul>
<p><li><tt>default</tt></li></p>
<p>Date value to be used as default for this field.</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag that indicates whether this field is constrained to not be set to <tt>NULL</tt>.</p>
</ul>
<p>The <tt>$declaration</tt> return value is the <i>DBMS</i> specific <i>SQL</i> code portion that should be used to declare the specified field.</p>
</ul>
<h4><a name="140.3.0"><a name="function_MetabaseGetTimestampFieldTypeDeclaration">MetabaseGetTimestampFieldTypeDeclaration</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$declaration=MetabaseGetTimestampFieldTypeDeclaration($database, $name, &amp;$field)</tt></p>
<h5>Purpose</h5>
<p>Obtain <i>DBMS</i> specific <i>SQL</i> code portion needed to declare an time stamp type field to be used in statements like <tt>CREATE TABLE</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name the field to be declared.</p>
<p>The <tt>$field</tt> argument is an associative array with the name of the properties of the field being declared as array indexes.  Currently, the types of supported field properties are as follows:</p>
<ul>
<p><li><tt>default</tt></li></p>
<p>Time stamp value to be used as default for this field.</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag that indicates whether this field is constrained to not be set to <tt>NULL</tt>.</p>
</ul>
<p>The <tt>$declaration</tt> return value is the <i>DBMS</i> specific <i>SQL</i> code portion that should be used to declare the specified field.</p>
</ul>
<h4><a name="142.3.0"><a name="function_MetabaseGetCLOBFieldTypeDeclaration">MetabaseGetCLOBFieldTypeDeclaration</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$declaration=MetabaseGetCLOBFieldTypeDeclaration($database, $name, &amp;$field)</tt></p>
<h5>Purpose</h5>
<p>Obtain <i>DBMS</i> specific <i>SQL</i> code portion needed to declare a character large object type field to be used in statements like <tt>CREATE TABLE</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name the field to be declared.</p>
<p>The <tt>$field</tt> argument is an associative array with the name of the properties of the field being declared as array indexes.  Currently, the types of supported field properties are as follows:</p>
<ul>
<p><li><tt>length</tt></li></p>
<p>Integer value that determines the maximum length of the large object field.  If this argument is missing the field should be declared to have the longest length allowed by the DBMS.</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag that indicates whether this field is constrained to not be set to <tt>NULL</tt>.</p>
</ul>
<p>The <tt>$declaration</tt> return value is the <i>DBMS</i> specific <i>SQL</i> code portion that should be used to declare the specified field.</p>
</ul>
<h4><a name="144.3.0"><a name="function_MetabaseGetBLOBFieldTypeDeclaration">MetabaseGetBLOBFieldTypeDeclaration</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$declaration=MetabaseGetBLOBFieldTypeDeclaration($database, $name, &amp;$field)</tt></p>
<h5>Purpose</h5>
<p>Obtain <i>DBMS</i> specific <i>SQL</i> code portion needed to declare a binary large object type field to be used in statements like <tt>CREATE TABLE</tt>.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name the field to be declared.</p>
<p>The <tt>$field</tt> argument is an associative array with the name of the properties of the field being declared as array indexes.  Currently, the types of supported field properties are as follows:</p>
<ul>
<p><li><tt>length</tt></li></p>
<p>Integer value that determines the maximum length of the large object field.  If this argument is missing the field should be declared to have the longest length allowed by the DBMS.</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag that indicates whether this field is constrained to not be set to <tt>NULL</tt>.</p>
</ul>
<p>The <tt>$declaration</tt> return value is the <i>DBMS</i> specific <i>SQL</i> code portion that should be used to declare the specified field.</p>
</ul>
<h4><a name="146.3.0"><a name="function_MetabaseCreateTable">MetabaseCreateTable</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseCreateTable($database, $name, $fields)</tt></p>
<h5>Purpose</h5>
<p>Create a new database table. This function is deprecated in favour of the <tt><a href="#function_MetabaseCreateDetailedTable">MetabaseCreateDetailedTable</a></tt> function, as this allows the creation of more complex tables, for instance with primary keys and auto-incremented key fields.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name of the table that is intended to be created.</p>
<p>The <tt>$fields</tt> argument is an associative array that contains the definition of each field of the new table.  The indexes of the array entries are the names of the fields of the table an the array entry values are associative arrays like those that are meant to be passed with the field definitions to <tt>MetabaseGet<i>Type</i>FieldTypeDeclaration</tt> functions.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in creating the new table.</p>
<h5>Example</h5>
<ul>
<p><tt>$table_name=&quot;users&quot;;</tt><br />
 <tt>$success=MetabaseCreateTable($database, &quot;users&quot;, array(</tt></p>
<ul>
<p><tt>&quot;id&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;type&quot;=&gt;&quot;integer&quot;,</tt><br />
 <tt>&quot;unsigned&quot;=&gt;1</tt><br />
 <tt>&quot;notnull&quot;=&gt;1</tt><br />
 <tt>&quot;default&quot;=&gt;0</tt></p>
</ul>
<p><tt>),</tt><br />
 <tt>&quot;name&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;type&quot;=&gt;&quot;text&quot;,</tt><br />
 <tt>&quot;length&quot;=&gt;12</tt></p>
</ul>
<p><tt>),</tt><br />
 <tt>&quot;password&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;type&quot;=&gt;&quot;text&quot;,</tt><br />
 <tt>&quot;length&quot;=&gt;12</tt></p>
</ul>
<p><tt>)</tt></p>
</ul>
<p><tt>));</tt><br />
 <tt>if(!$success)</tt><br />
 <tt>{</tt></p>
<ul>
<p><tt>echo &quot;Error while creating the database table &quot;users&quot;: &quot;,MetabaseError($database);</tt><br />
 <tt>exit;</tt></p>
</ul>
<p><tt>}</tt><br />
</p>
</ul>
</ul>
<h4><a name="153.3.0"><a name="function_MetabaseCreateDetailedTable">MetabaseCreateDetailedTable</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseCreateDetailedTable($database, $table, $check)</tt></p>
<h5>Purpose</h5>
<p>Create a new database table that may include other details besides the fields list, such as the table primary key. This function may optionally simulate the creation of a table to determine whether the current <i>DBMS</i> driver class is capable of creating a table with the given definition.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is a reference to an associative array variable that specifies the definition of the table that is intended to be created.</p>
<ul>
<p>Here follow the list of entries of the definition associative array:</p>
<p><li><tt>name</tt> (required)</li></p>
<p>The <tt>name</tt> argument entry is the name of the table that is intended to be created.</p>
<p><li><tt>FIELDS</tt> (required)</li></p>
<p>The <tt>FIELDS</tt> argument entry is an associative array that contains the definition of each field of the new table. This is the same as the <tt>$fields</tt> parameter of the <tt><a href="#function_MetabaseCreateTable">MetabaseCreateTable</a></tt> function.</p>
<p><li><tt>PRIMARYKEY</tt> (required if the table has an auto-incremented key field)</li></p>
<p>The <tt>PRIMARYKEY</tt> argument entry is an associative array that contains the parameters of the key. It must have an entry named <tt>FIELDS</tt> that is another associative array that lists fields that compose the table primary key, just like the <tt>FIELDS</tt> definition for the <tt><a href="#function_MetabaseCreateIndex">MetabaseCreateIndex</a></tt> function.</p>
</ul>
<p>The <tt>$check</tt> argument is a boolean flag value that determines whether the function should simulate the creation of the table or create it for real. If this argument is <tt>1</tt>, this function will not create the table but may fail in case the <i>DBMS</i> driver class would not be able to create a table with the requested definition.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in creating the new table, or whether the function could create a table with the requested definition if the <tt>$check</tt> variable is <tt>1</tt>.</p>
<h5>Example</h5>
<ul>
<pre>
$table=array(

  &quot;name&quot;=&gt;&quot;users&quot;,

  &quot;FIELDS&quot;=&gt;array(

    &quot;id&quot;=&gt;array(

      &quot;type&quot;=&gt;&quot;integer&quot;,
      &quot;autoincrement&quot;=&gt;1

    ),
    &quot;name&quot;=&gt;array(

      &quot;type&quot;=&gt;&quot;text&quot;,
      &quot;length&quot;=&gt;12

    ),
    &quot;password&quot;=&gt;array(

      &quot;type&quot;=&gt;&quot;text&quot;,
      &quot;length&quot;=&gt;12

    )

  ),
  &quot;PRIMARYKEY&quot;=&gt;array(

    &quot;FIELDS&quot;=&gt;array(

      &quot;id&quot;=&gt;array(&quot;sorting&quot;=&gt;&quot;ascending&quot;)

    )

  )

);

$success=MetabaseCreateDetailedTable($database, $table, 0);

if(!$success)
{
	echo &quot;Error while creating the database table 'users': &quot;,MetabaseError($database),&quot;\n&quot;
	exit;
}
</pre>
</ul>
</ul>
<h4><a name="156.3.0"><a name="function_MetabaseDropTable">MetabaseDropTable</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseDropTable($database, $name)</tt></p>
<h5>Purpose</h5>
<p>Drop an existing database table. This function is deprecated in favour of the <tt><a href="#function_MetabaseDropDetailedTable">MetabaseDropDetailedTable</a></tt> function, as this allows dropping more complex tables, for instance with primary keys and auto-incremented key fields.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name of the table that is intended to be dropped.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in dropping the specified table.</p>
</ul>
<h4><a name="157.3.0"><a name="function_MetabaseDropDetailedTable">MetabaseDropDetailedTable</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseDropDetailedTable($database, $table, $check)</tt></p>
<h5>Purpose</h5>
<p>Drop an existing database table that may include other details besides the fields list, such as the table primary key. This function may optionally simulate dropping the table to determine whether the current <i>DBMS</i> driver class is capable of dropping table with the given definition.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is reference to an associative array variable that specifies the definition of the table that is intended to be dropped, just like the <tt>$table</tt> argument of the function <tt><a href="#function_MetabaseCreateDetailedTable">MetabaseCreateDetailedTable</a></tt>.</p>
<p>The <tt>$check</tt> argument is a boolean flag value that determines whether the function should simulate dropping the table or drop it for real. If this argument is <tt>1</tt>, this function will not drop the table but may fail in case the <i>DBMS</i> driver class would not be able to drop a table with the given definition.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in dropping the new table, or whether the function could drop a table with the given definition if the <tt>$check</tt> variable is <tt>1</tt>.</p>
</ul>
<h4><a name="158.3.0"><a name="function_MetabaseAlterTable">MetabaseAlterTable</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseAlterTable($database, $name, $changes, $check)</tt></p>
<h5>Purpose</h5>
<p>Perform a list of changes in a database table.  This function is also able to check if the <i>DBMS</i> driver is able to perform the listed changes without actually making them.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name of the table that is intended to be changed.</p>
<p>The <tt>$changes</tt> argument is an associative array that contains the details of each type of change that is intended to be performed.  The types of changes that are currently supported are defined as follows:</p>
<ul>
<p><li><tt>name</tt></li></p>
<p>New name for the table.</p>
<p><li><tt>AddedFields</tt></li></p>
<p>Associative array with the names of fields to be added as indexes of the array.  The value of each entry of the array should be set to another associative array with the properties of the fields to be added.  The properties of the fields should be the same as defined by the <b>Metabase</b> parser.</p>
<p>Additionally, there should be an entry named <tt>Declaration</tt> that is expected to contain the portion of the field declaration already in <i>DBMS</i> specific <i>SQL</i> code as it is used in the <tt>CREATE TABLE</tt> statement.</p>
<p><li><tt>RemovedFields</tt></li></p>
<p>Associative array with the names of fields to be removed as indexes of the array.  Currently the values assigned to each entry are ignored.  An empty array should be used for future compatibility.</p>
<p><li><tt>RenamedFields</tt></li></p>
<p>Associative array with the names of fields to be renamed as indexes of the array. The value of each entry of the array should be set to another associative array with the entry named <tt>name</tt> with the new field name and the entry named <tt>Declaration</tt> that is expected to contain the portion of the field declaration already in <i>DBMS</i> specific <i>SQL</i> code as it is used in the <tt>CREATE TABLE</tt> statement.</p>
<p><li><tt>ChangedFields</tt></li></p>
<p>Associative array with the names of the fields to be changed as indexes of the array.  Keep in mind that if it is intended to change either the name of a field and any other properties, the <tt>ChangedFields</tt> array entries should have the new names of the fields as array indexes.</p>
<p>The value of each entry of the array should be set to another associative array with the properties of the fields to that are meant to be changed as array entries.  These entries should be assigned to the new values of the respective properties.  The properties of the fields should be the same as defined by the <b>Metabase</b> parser.</p>
<p>If the <tt>default</tt> property is meant to be added, removed or changed, there should also be an entry with index <tt>ChangedDefault</tt> assigned to <tt>1</tt>. Similarly, if the <tt>notnull</tt> constraint is to be added or removed, there should also be an entry with index <tt>ChangedNotNull</tt> assigned to <tt>1</tt>.</p>
<p>Additionally, there should be an entry named <tt>Declaration</tt> that is expected to contain the portion of the field changed declaration already in <i>DBMS</i> specific <i>SQL</i> code as it is used in the <tt>CREATE TABLE</tt> statement.</p>
</ul>
<p>The <tt>$check</tt> argument is a boolean flag value that indicates whether the function should just check if the <i>DBMS</i> driver can perform the requested table alterations if the value is <tt>1</tt> or actually perform them otherwise.</p>
<p>The <tt>$success</tt> return value indicates whether the <i>DBMS</i> driver is able to attempt to perform the requested changes if the <tt>$check</tt> argument is <tt>1</tt> or if the function call succeeded in altering the table otherwise.</p>
<h5>Example</h5>
<ul>
<p><tt>$table_name=&quot;users&quot;;</tt><br />
 <tt>$success=MetabaseAlterTable($database, $name, array(</tt></p>
<ul>
<p><tt>&quot;name&quot;=&gt;&quot;userlist&quot;,</tt><br />
 <tt>&quot;AddedFields&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;quota&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;type&quot;=&gt;&quot;integer&quot;,</tt><br />
 <tt>&quot;unsigned&quot;=&gt;1</tt><br />
 <tt>&quot;Declaration&quot;=&gt;&quot;quota INT&quot;</tt></p>
</ul>
<p><tt>)</tt></p>
</ul>
<p><tt>),</tt><br />
 <tt>&quot;RemovedFields&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;file_limit&quot;=&gt;array(),</tt><br />
 <tt>&quot;time_limit&quot;=&gt;array()</tt></p>
</ul>
<p><tt>),</tt><br />
 <tt>&quot;ChangedFields&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;gender&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;default&quot;=&gt;&quot;M&quot;,</tt><br />
 <tt>&quot;ChangeDefault&quot;=&gt;1,</tt><br />
 <tt>&quot;Declaration&quot;=&gt;&quot;gender CHAR(1) DEFAULT 'M'&quot;</tt></p>
</ul>
<p><tt>)</tt></p>
</ul>
<p><tt>),</tt><br />
 <tt>&quot;RenamedFields&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;sex&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;name&quot;=&gt;&quot;gender&quot;,</tt><br />
 <tt>&quot;Declaration&quot;=&gt;&quot;gender CHAR(1) DEFAULT 'M'&quot;</tt></p>
</ul>
<p><tt>)</tt></p>
</ul>
<p><tt>)</tt></p>
</ul>
<p><tt>), 0);</tt><br />
 <br />
 <tt>if(!$success)</tt><br />
 <tt>{</tt></p>
<ul>
<p><tt>echo &quot;Error while altering the database table $table_name: &quot;,MetabaseError($database);</tt><br />
 <tt>exit;</tt></p>
</ul>
<p><tt>}</tt><br />
</p>
</ul>
</ul>
</ul>
<h3><a name="170.2.0">Sequences</a></h3>
<ul>
<p>Sequences are database objects that store integer numbers. A sequence value is automatically incremented when it is accessed.  Sequences are useful for applications that need to have table fields on which each row has to have a unique value.</p>
<p>For this purpose, auto-incremented key fields are more recommended. However, not all <b>Metabase</b> drivers support auto-incremented fields.</p>
<p>Not all <i>DBMS</i> support database sequence objects either. However, for those <i>DBMS</i> that do not support sequences, if possible, some <i>DBMS</i> drivers emulate them by creating separate tables with fields with the <tt>AUTO_INCREMENT</tt> property.  Use the function <tt><a href="#function_MetabaseSupport">MetabaseSupport</a></tt> to determine whether the <i>DBMS</i> driver support either database sequence objects or auto-incremented key fields.</p>
<h4><a name="171.3.0"><a name="function_MetabaseCreateSequence">MetabaseCreateSequence</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseCreateSequence($database, $name, $start)</tt></p>
<h5>Purpose</h5>
<p>Create a database sequence object.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name of the sequence to be created.</p>
<p>The <tt>$start</tt> argument is the initial integer value of the sequence to be created.  Usually, this value is set to <tt>1</tt>.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in creating the database sequence object.</p>
</ul>
<h4><a name="172.3.0"><a name="function_MetabaseDropSequence">MetabaseDropSequence</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$support=MetabaseDropSequence($database, $name)</tt></p>
<h5>Purpose</h5>
<p>Drop an existing database sequence object.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name of the sequence to be dropped.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in dropping the database sequence object.</p>
</ul>
<h4><a name="173.3.0"><a name="function_MetabaseGetSequenceNextValue">MetabaseGetSequenceNextValue</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseGetSequenceNextValue($database, $name, &amp;$value)</tt></p>
<h5>Purpose</h5>
<p>Get the next value of a sequence and increment its current value.  Both operation are execute atomically by the <i>DBMS</i>. If more than one application attempts to access simultaneously to a sequence, it is assured that each one will get a different value without corrupting the sequence.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name of the sequence to be accessed.</p>
<p>The <tt>$value</tt> argument is a reference to an integer variable on which it will be stored the next sequence value.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in accessing to the sequence next value.</p>
</ul>
<h4><a name="174.3.0"><a name="function_MetabaseGetSequenceCurrentValue">MetabaseGetSequenceCurrentValue</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseGetSequenceCurrentValue($database, $name, &amp;$value)</tt></p>
<h5>Purpose</h5>
<p>Get the current value of a sequence.  The value returned by this function may not be useful if there may be multiple applications simultaneously accessing the specified sequence.</p>
<p>Not all <i>DBMS</i> drivers that support sequences are able to determine the current value of the sequences.  Use the function <tt><a href="#function_MetabaseSupport">MetabaseSupport</a></tt> to determine whether the <i>DBMS</i> driver has this ability.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$name</tt> argument is the name of the sequence to be accessed.</p>
<p>The <tt>$value</tt> argument is a reference to an integer variable on which it will be stored the current sequence value.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in accessing to the sequence current value.</p>
</ul>
</ul>
<h3><a name="175.2.0">Indexes</a></h3>
<ul>
<p>Indexes are database objects intended make more efficient the searches for information in tables.  Although it does not require any changes in the way the information is accessed, the use of indexes may drastically reduce the amount of time that is necessary to look for information specified in the query statements search clause.</p>
<p>An index is created by specifying a set of one or more fields of a table.  The fields to be picked for the index creation should be the same that are used in the search clause of each query	that is intended to be optimized.</p>
<p>The decision to create indexes for each table should not be made lightly.  While using indexes may reduce the time that a query on a table may take, it also increases the time that takes to insert new rows on that table, as that causes all its indexes to be regenerated.  Also, each new index requires more disk space and memory to be managed.  Therefore, database designers have to balance these aspects before deciding which indexes are worthy to be created.</p>
<p>Not all <i>DBMS</i> support indexes, despite most do.  Use the function <tt><a href="#function_MetabaseSupport">MetabaseSupport</a></tt> to determine whether the <i>DBMS</i> driver in use can manage indexes.</p>
<h4><a name="176.3.0"><a name="function_MetabaseCreateIndex">MetabaseCreateIndex</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseCreateIndex($database, $table, $name, $definition)</tt></p>
<h5>Purpose</h5>
<p>Create a new table index.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is the name of the table on which the index is to be created.</p>
<p>The <tt>$name</tt> argument is the name of the index to be created.</p>
<p>The <tt>$definition</tt> argument is an associative array that defines properties of the index to be created. It must defined one property named <tt>FIELDS</tt> that is an associative with the names of the index fields as array indexes.  Each entry of this array is set to another type of associative array that specifies properties of the index that are specific to each field.</p>
<p>Currently, only the <tt>sorting</tt> property is supported.  It should be used to define the sorting direction of the index. It may be set to either <tt>ascending</tt> or <tt>descending</tt>.</p>
<p>Not all <i>DBMS</i> support index sorting direction configuration.  The <i>DBMS</i> drivers of those that do not support it ignore this property.  Use the function <tt><a href="#function_MetabaseSupport">MetabaseSupport</a></tt> to determine whether the <i>DBMS</i> driver can manage indexes.</p>
<p>The index definition argument may contain also a boolean property named <tt>unique</tt>. When it is set to <tt>1</tt> it specifies that the combination of the values of the index fields on each row of the table should unique.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in creating the specified index.</p>
<h5>Example</h5>
<ul>
<p><tt>$table_name=&quot;users&quot;;</tt><br />
 <tt>$success=MetabaseCreateIndex($database, $table_name, &quot;users_index&quot;, array(</tt></p>
<ul>
<p><tt>&quot;FIELDS&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;user_name&quot;=&gt;array(</tt></p>
<ul>
<p><tt>&quot;sorting&quot;=&gt;&quot;ascending&quot;</tt></p>
</ul>
<p><tt>),</tt><br />
 <tt>&quot;last_login&quot;=&gt;array()</tt></p>
</ul>
<p><tt>)</tt></p>
</ul>
<p><tt>));</tt><br />
 <br />
 <tt>if(!$success)</tt><br />
 <tt>{</tt></p>
<ul>
<p><tt>echo &quot;Error creating a database index for table $table_name: &quot;,MetabaseError($database);</tt><br />
 <tt>exit;</tt></p>
</ul>
<p><tt>}</tt><br />
</p>
</ul>
</ul>
<h4><a name="182.3.0"><a name="function_MetabaseDropIndex">MetabaseDropIndex</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseDropIndex($database, $table, $name)</tt></p>
<h5>Purpose</h5>
<p>Drop an existing table index.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is the name of the table on which the index was created.</p>
<p>The <tt>$name</tt> argument is the name of the index to be dropped.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in dropping the specified index.</p>
</ul>
</ul>
<h3><a name="183.2.0">Schema reverse engineering</a></h3>
<ul>
<p>Despite <b>Metabase</b> provides schema creation and maintenance support functions, the <b>Metabase</b> API functions can also access databases that were created by some other process.  However, it is recommended that you install database schemas with <b>Metabase</b> manager to use with your database applications based on <b>Metabase</b> API.</p>
<p>If you have a database application that you want to migrate to start using <b>Metabase</b>, there is a set of functions that you can use to migrate your database schemas by performing <b>reverse engineering</b>.</p>
<p>Keep in mind that the current schema reverse engineering support is experimental. This means that what is provided is not a complete solution. You may need to correct manually the reverse engineered schemas generated by <b>Metabase</b>. Depending on some reverse engineering decisions, any data that may already exist in the legacy database may need to be converted. However, there is not yet support to migrate data from a database with a reverse engineered schema. Future versions of <b>Metabase</b> API will address these limitations.</p>
<p><b>Metabase</b> API only provides functions that are needed to retrieve schema information for the reverse engineering process. The actual assembly of the information to produce a reverse engineered schema is made by the <tt><a href="#function_GetDefinitionFromDatabase">GetDefinitionFromDatabase</a></tt> of the database manager class.</p>
<h4><a name="184.3.0"><a name="function_MetabaseListTables">MetabaseListTables</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseListTables($database, $tables)</tt></p>
<h5>Purpose</h5>
<p>Retrieve the list of tables in the current database.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$tables</tt> argument is a reference to an array variable in which it will be returned the list of database tables.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the database tables.</p>
</ul>
<h4><a name="185.3.0"><a name="function_MetabaseListTableFields">MetabaseListTableFields</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseListTableFields($database, $table, $fields)</tt></p>
<h5>Purpose</h5>
<p>Retrieve the list of fields of a given table of the current database.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is the name of the table to list its fields.</p>
<p>The <tt>$fields</tt> argument is a reference to an array variable in which it will be returned the list of table fields.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the list of table fields.</p>
</ul>
<h4><a name="186.3.0"><a name="function_MetabaseGetTableFieldDefinition">MetabaseGetTableFieldDefinition</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseGetTableFieldDefinition($database, $table, $field, $definition)</tt></p>
<h5>Purpose</h5>
<p>Retrieve the definition of a given table field of the database. This function performs a mapping between the field native definition and the database independent field definition used by <b>Metabase</b>.</p>
<p>Sometimes the field definition mapping may be ambiguous because the developer that created the original schema may have used some data types to emulate other data types. For instance, often it is used a text field of one character of length to emulate boolean fields.</p>
<p>In case of ambiguity, this function will return multiple definitions to describe all the possible field definitions mappings that may be valid. The first definition that is returned in <tt>$definition</tt> argument array is the one that seems to be more likely, so it can be used by applications that are only interested in the best guess definition.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is the name of the table of the field to get its definition.</p>
<p>The <tt>$field</tt> argument is the name of the table field to get its definition.</p>
<p>The <tt>$definition</tt> argument is a reference to an array variable in which it will be returned one or more possible definitions of the table field. Each entry of the array is an associative array that contains the definition of the properties of the field. The names and values of the properties in the definition array are the same defined in the <a href="#schema_description">schema description data structure</a> for table fields.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the definition of the table field.</p>
</ul>
<h4><a name="187.3.0"><a name="function_MetabaseListTableKeys">MetabaseListTableKeys</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseListTableKeys($database, $table, $primary, $keys)</tt></p>
<h5>Purpose</h5>
<p>Retrieve the list of keys of a given table of the current database.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is the name of the table to list its keys.</p>
<p>The <tt>$primary</tt> argument is boolean flag that determines whether it should be returned the table primary key or others.</p>
<p>The <tt>$keys</tt> argument is a reference to an array variable in which it will be returned the list of table keys.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the list of table keys.</p>
</ul>
<h4><a name="188.3.0"><a name="function_MetabaseGetTableKeyDefinition">MetabaseGetTableKeyDefinition</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseGetTableKeyDefinition($database, $table, $key, $primary, $definition)</tt></p>
<h5>Purpose</h5>
<p>Retrieve the definition of a given table key of the database.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is the name of the table of the index to get its definition.</p>
<p>The <tt>$key</tt> argument is the name of the table key to get its definition.</p>
<p>The <tt>$primary</tt> argument is boolean flag that indicates whether the specified key is the table primary key or of other type.</p>
<p>The <tt>$definition</tt> argument is a reference to an array variable in which it will be returned the definition of the table key. The associative array contains the definition of the properties of the key. The names and values of the properties in the definition array are the same defined in the <a href="#schema_description">schema description data structure</a> for table keys.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the table key definition.</p>
</ul>
<h4><a name="189.3.0"><a name="function_MetabaseListTableIndexes">MetabaseListTableIndexes</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseListTableIndexes($database, $table, $indexes)</tt></p>
<h5>Purpose</h5>
<p>Retrieve the list of indexes of a given table of the current database.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is the name of the table to list its indexes.</p>
<p>The <tt>$indexes</tt> argument is a reference to an array variable in which it will be returned the list of table indexes.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the list of table indexes.</p>
</ul>
<h4><a name="190.3.0"><a name="function_MetabaseGetTableIndexDefinition">MetabaseGetTableIndexDefinition</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseGetTableIndexDefinition($database, $table, $index, $definition)</tt></p>
<h5>Purpose</h5>
<p>Retrieve the definition of a given table index of the database.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$table</tt> argument is the name of the table of the index to get its definition.</p>
<p>The <tt>$index</tt> argument is the name of the table index to get its definition.</p>
<p>The <tt>$definition</tt> argument is a reference to an array variable in which it will be returned the definition of the table index. The associative array contains the definition of the properties of the index. The names and values of the properties in the definition array are the same defined in the <a href="#schema_description">schema description data structure</a> for table indexes.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the table index definition.</p>
</ul>
<h4><a name="191.3.0"><a name="function_MetabaseListSequences">MetabaseListSequences</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseListSequences($database, $sequences)</tt></p>
<h5>Purpose</h5>
<p>Retrieve the list of sequences of the current database.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$sequences</tt> argument is a reference to an array variable in which it will be returned the list of sequences.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the list of sequences.</p>
</ul>
<h4><a name="192.3.0"><a name="function_MetabaseGetSequenceDefinition">MetabaseGetSequenceDefinition</a></a></h4>
<ul>
<h5>Synopsis</h5>
<p><tt>$success=MetabaseGetSequenceDefinition($database, $sequence, $definition)</tt></p>
<h5>Purpose</h5>
<p>Retrieve the definition of a given sequence of the database.</p>
<h5>Usage</h5>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$sequence</tt> argument is the name of the sequence to get its definition.</p>
<p>The <tt>$definition</tt> argument is a reference to an array variable in which it will be returned the definition of the sequence. The associative array contains the definition of the properties of the sequence. The names and values of the properties in the definition array are the same defined in the <a href="#schema_description">schema description data structure</a> for sequences.</p>
<p>The <tt>$success</tt> return value indicates whether the function call succeeded in retrieving the sequence definition.</p>
</ul>
</ul>
</ul>
<h2><li><a name="193.1.9">Debugging</a></li></h2>
<ul>
<h3><a name="194.2.0"><a name="function_MetabaseCaptureDebugOutput">MetabaseCaptureDebugOutput</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>MetabaseCaptureDebugOutput($database, $capture)</tt></p>
<h4>Purpose</h4>
<p>Set the debugging function to an internal function that captures the output generated by calls to <tt><a href="#function_MetabaseDebug">MetabaseDebug</a></tt> functions.  The captured debug output information maybe retrieved with the function <tt><a href="#function_MetabaseDebugOutput">MetabaseDebugOutput</a></tt>.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$capture</tt> argument is a boolean flag that indicates whether the debug output capture is meant to be enabled or disabled.  If this argument is set to <tt>0</tt>, the debug output handling function is reset and debugging calls are ignored.</p>
</ul>
<h3><a name="195.2.0"><a name="function_MetabaseDebugOutput">MetabaseDebugOutput</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$debug_output=MetabaseDebugOutput($database)</tt></p>
<h4>Purpose</h4>
<p>Retrieve the debug output information captured so far from calls to <i>Metabase</i> functions within the context associated with the given database access handle. When this function is called, the debug output buffer is emptied.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$debug_output</tt> return value is a text string that comprises all the debug output that was captured so far.</p>
</ul>
<h3><a name="196.2.0"><a name="function_MetabaseDebug">MetabaseDebug</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>MetabaseDebug($database, $message)</tt></p>
<h4>Purpose</h4>
<p>Send a debug output message to the current debugging handling function.  If no debug output handling function is set, nothing happens.</p>
<h4>Usage</h4>
<p>The <tt>$database</tt> argument is a database access handle that was returned by the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$message</tt> argument is a text string the message that is meant to be outputted for debugging purposes.</p>
</ul>
</ul>
</ul>
<hr />
<h1><a name="197.0"><i>DBMS</i> specific drivers</a></h1>
<ul>
<p>The access to each of the supported <i>DBMS</i> is implemented by objects of driver classes.  Application developers do not have to manage the driver objects directly, that is the role of <b>Metabase</b> applications programming interface functions.</p>
<p>When the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function is called, it determines which driver class should be used and creates an object of that class.  The database access handle that is returned by this function is an indirect reference to the driver class object that is created.  The other <b>Metabase</b> interface functions use that database access handle to call the respective driver class object functions or manipulate its variables.</p>
<p>All <b>Metabase</b> driver classes provide the same set of functions and object variables.  <b>Metabase</b> comes with a base class to simplify driver class development.  All the driver classes are derived from the base class. This base class provides the default definition for all the driver object functions.  Driver classes only have to redefine the functions that should be implemented differently from the base class to access properly to the respective <b>DBMS</b>.</p>
<h2><a name="198.1.0"><li>Driver class functions</li></a></h2>
<p><b>Metabase</b> driver classes have two types of functions: public and private.</p>
<p>The driver class public functions may be called by applications using the applications programming interface functions.  Most of these functions only serve as stubs that do not do more than call the driver class functions.  Their arguments are the same except for the database access handle argument that is dereferenced and so it is not passed when calling the driver class functions.</p>
<p>Public functions have the same as the interface functions without the <tt>Metabase</tt> prefix.  The applications programming interface documentation has all details on their usage.  Here follows the complete list of the driver class public functions:</p>
<ul>
<p><li><tt>AffectedRows</tt></li></p>
<p><li><tt>AlterTable</tt></li></p>
<p><li><tt>AutoCommitTransactions</tt></li></p>
<p><li><tt>BaseConvertResult</tt></li></p>
<p><li><tt>BaseFetchResultArray</tt></li></p>
<p><li><tt>CaptureDebugOutput</tt></li></p>
<p><li><tt>Close</tt></li></p>
<p><li><tt>CloseSetup</tt></li></p>
<p><li><tt>CommitTransaction</tt></li></p>
<p><li><tt>ConvertResult</tt></li></p>
<p><li><tt>ConvertResultRow</tt></li></p>
<p><li><tt>CreateDatabase</tt></li></p>
<p><li><tt>CreateIndex</tt></li></p>
<p><li><tt>CreateSequence</tt></li></p>
<p><li><tt>CreateDetailedTable</tt></li></p>
<p><li><tt>Debug</tt></li></p>
<p><li><tt>DebugOutput</tt></li></p>
<p><li><tt>DestroyResultLOB</tt></li></p>
<p><li><tt>DropDatabase</tt></li></p>
<p><li><tt>DropIndex</tt></li></p>
<p><li><tt>DropSequence</tt></li></p>
<p><li><tt>DropDetailedTable</tt></li></p>
<p><li><tt>EndOfResult</tt></li></p>
<p><li><tt>EndOfResultLOB</tt></li></p>
<p><li><tt>Error</tt></li></p>
<p><li><tt>ExecutePreparedQuery</tt></li></p>
<p><li><tt>ExecuteQuery</tt></li></p>
<p><li><tt>FetchBLOBResult</tt></li></p>
<p><li><tt>FetchBooleanResult</tt></li></p>
<p><li><tt>FetchCLOBResult</tt></li></p>
<p><li><tt>FetchDateResult</tt></li></p>
<p><li><tt>FetchDecimalResult</tt></li></p>
<p><li><tt>FetchFloatResult</tt></li></p>
<p><li><tt>FetchLOBResult</tt></li></p>
<p><li><tt>FetchResult</tt></li></p>
<p><li><tt>FetchResultAll</tt></li></p>
<p><li><tt>FetchResultArray</tt></li></p>
<p><li><tt>FetchResultColumn</tt></li></p>
<p><li><tt>FetchResultField</tt></li></p>
<p><li><tt>FetchResultRow</tt></li></p>
<p><li><tt>FetchTimeResult</tt></li></p>
<p><li><tt>FetchTimestampResult</tt></li></p>
<p><li><tt>FreeBLOBValue</tt></li></p>
<p><li><tt>FreeCLOBValue</tt></li></p>
<p><li><tt>FreePreparedQuery</tt></li></p>
<p><li><tt>FreeResult</tt></li></p>
<p><li><tt>GetBLOBFieldTypeDeclaration</tt></li></p>
<p><li><tt>GetBLOBFieldValue</tt></li></p>
<p><li><tt>GetBooleanFieldTypeDeclaration</tt></li></p>
<p><li><tt>GetBooleanFieldValue</tt></li></p>
<p><li><tt>GetCLOBFieldTypeDeclaration</tt></li></p>
<p><li><tt>GetCLOBFieldValue</tt></li></p>
<p><li><tt>GetColumnNames</tt></li></p>
<p><li><tt>GetDateFieldTypeDeclaration</tt></li></p>
<p><li><tt>GetDateFieldValue</tt></li></p>
<p><li><tt>GetDecimalFieldTypeDeclaration</tt></li></p>
<p><li><tt>GetDecimalFieldValue</tt></li></p>
<p><li><tt>GetFieldValue</tt></li></p>
<p><li><tt>GetFloatFieldTypeDeclaration</tt></li></p>
<p><li><tt>GetFloatFieldValue</tt></li></p>
<p><li><tt>GetInsertedKey</tt></li></p>
<p><li><tt>GetIntegerFieldTypeDeclaration</tt></li></p>
<p><li><tt>GetIntegerFieldValue</tt></li></p>
<p><li><tt>GetNextKey</tt></li></p>
<p><li><tt>GetSequenceCurrentValue</tt></li></p>
<p><li><tt>GetSequenceDefinition</tt></li></p>
<p><li><tt>GetSequenceNextValue</tt></li></p>
<p><li><tt>GetTableFieldDefinition</tt></li></p>
<p><li><tt>GetTableIndexDefinition</tt></li></p>
<p><li><tt>GetTableKeyDefinition</tt></li></p>
<p><li><tt>GetTextFieldTypeDeclaration</tt></li></p>
<p><li><tt>GetTextFieldValue</tt></li></p>
<p><li><tt>GetTimeFieldTypeDeclaration</tt></li></p>
<p><li><tt>GetTimeFieldValue</tt></li></p>
<p><li><tt>GetTimestampFieldTypeDeclaration</tt></li></p>
<p><li><tt>GetTimestampFieldValue</tt></li></p>
<p><li><tt>ListSequences</tt></li></p>
<p><li><tt>ListTableFields</tt></li></p>
<p><li><tt>ListTableIndexes</tt></li></p>
<p><li><tt>ListTableKeys</tt></li></p>
<p><li><tt>ListTables</tt></li></p>
<p><li><tt>NumberOfColumns</tt></li></p>
<p><li><tt>NumberOfRows</tt></li></p>
<p><li><tt>PrepareQuery</tt></li></p>
<p><li><tt>Query</tt></li></p>
<p><li><tt>QueryAll</tt></li></p>
<p><li><tt>QueryColumn</tt></li></p>
<p><li><tt>QueryField</tt></li></p>
<p><li><tt>QueryRow</tt></li></p>
<p><li><tt>QuerySet</tt></li></p>
<p><li><tt>QuerySetBLOB</tt></li></p>
<p><li><tt>QuerySetBoolean</tt></li></p>
<p><li><tt>QuerySetCLOB</tt></li></p>
<p><li><tt>QuerySetDate</tt></li></p>
<p><li><tt>QuerySetDecimal</tt></li></p>
<p><li><tt>QuerySetFloat</tt></li></p>
<p><li><tt>QuerySetInteger</tt></li></p>
<p><li><tt>QuerySetKey</tt></li></p>
<p><li><tt>QuerySetNull</tt></li></p>
<p><li><tt>QuerySetText</tt></li></p>
<p><li><tt>QuerySetTime</tt></li></p>
<p><li><tt>QuerySetTimestamp</tt></li></p>
<p><li><tt>ReadResultLOB</tt></li></p>
<p><li><tt>Replace</tt></li></p>
<p><li><tt>ResultIsNull</tt></li></p>
<p><li><tt>RetrieveLOB</tt></li></p>
<p><li><tt>RollbackTransaction</tt></li></p>
<p><li><tt>SetDatabase</tt></li></p>
<p><li><tt>SetError</tt></li></p>
<p><li><tt>SetErrorHandler</tt></li></p>
<p><li><tt>SetResultTypes</tt></li></p>
<p><li><tt>SetSelectedRowRange</tt></li></p>
<p><li><tt>Setup</tt></li></p>
<p><li><tt>Support</tt></li></p>
</ul>
<p>The driver class private functions should not be called directly from the applications.  There are two types of private functions: internal and external.</p>
<p>Internal functions are only meant to execute a driver specific action.  These functions are not documented because they should only be called from driver class and so they have no interest to application developers.</p>
<p>External functions are only meant to be called from interface functions.  Currently they only implement initialization and termination functions.</p>
<ul>
<h3><a name="200.2.0">Setup</a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=$driver_object-&gt;Setup()</tt></p>
<h4>Purpose</h4>
<p>Initialize the driver object internal state.  This function is called from within the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> after creating the driver object.  Most driver classes do not do anything in this function, but a few other classes need to evaluate the options set from <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> to initialize internal variables.</p>
<h4>Usage</h4>
<p>The <tt>$error</tt> return value contains an error message if this function call did not succeed.  Otherwise it contains an empty string.  This return value may be safely ignored if the database setup options are correctly defined.</p>
</ul>
<h3><a name="201.2.0">Close</a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$driver_object-&gt;Close()</tt></p>
<h4>Purpose</h4>
<p>Release any resources allocated during the driver object life time.  This function is called from within the <tt><a href="#function_MetabaseCloseSetup">MetabaseCloseSetup</a></tt> before destroying the driver object.  Most driver classes do not do anything in this function, but a few other classes need to check and free any resources that may be reused by the applications.</p>
</ul>
</ul>
<h2><a name="202.1.1"><li>Driver object variables</li></a></h2>
<p>The driver objects may use either private or public variables. Private variables are only meant for internal usage.  Public variables are only meant to be directly accessed from the applications programming interface functions.</p>
<p>Most public variables are used to store values that are initialized within the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function. These variables have names that are similar to the names of the options of that function.  The only exception is the <tt>database_name</tt> variable.  This variable is used by the <tt><a href="#function_MetabaseSetDatabase">MetabaseSetDatabase</a></tt> to store the name of the current database being accessed.  Here follows a list of all public driver variables.</p>
<ul>
<p><li><tt>host</tt></li></p>
<p><li><tt>user</tt></li></p>
<p><li><tt>password</tt></li></p>
<p><li><tt>persistent</tt></li></p>
<p><li><tt>decimal_places</tt></li></p>
<p><li><tt>options</tt></li></p>
<p><li><tt>database_name</tt></li></p>
<p><li><tt>lob_buffer_length</tt></li></p>
</ul>
<h2><a name="203.1.2"><li>Driver class extensions</li></a></h2>
<p><b>Metabase</b> API is already very large. Each complete driver is made by a reasonably large body of code. However, part of this code is not needed all the time. So, it can be loaded on demand to let the main driver class load faster and save some memory. For this reason, part of the drivers code is off-loaded to driver class extensions.</p>
<ul>
<h3><a name="204.2.0"><li>Manager extension</li></a></h3>
<p>Currently the only driver class extension that is supported is the one that implements schema management functions. These functions are usually needed only at database installation time. The schema management extension is loaded only when any of those functions is called for the first time. <b>Metabase</b> driver base class implements these functions by loading the manager extension class and calling the respective functions of that class.</p>
<p>Currently the manager driver extensions should implement these functions:</p>
<ul>
<p><tt>CreateDatabase</tt></p>
<p><tt>DropDatabase</tt></p>
<p><tt>CreateDetailedTable</tt></p>
<p><tt>DropDetailedTable</tt></p>
<p><tt>AlterTable</tt></p>
<p><tt>ListTables</tt></p>
<p><tt>ListTableFields</tt></p>
<p><tt>GetTableFieldDefinition</tt></p>
<p><tt>ListTableKeys</tt></p>
<p><tt>GetTableKeyDefinition</tt></p>
<p><tt>ListTableIndexes</tt></p>
<p><tt>GetTableIndexDefinition</tt></p>
<p><tt>ListSequences</tt></p>
<p><tt>GetSequenceDefinition</tt></p>
<p><tt>CreateIndex</tt></p>
<p><tt>DropIndex</tt></p>
<p><tt>CreateSequence</tt></p>
<p><tt>DropSequence</tt></p>
<p><tt>GetSequenceCurrentValue</tt></p>
</ul>
<p>Driver classes should also define these private variables in case they have a manager extension class:</p>
<ul>
<p><tt>manager_include</tt></p>
<p>File that contains the manager extension driver class.</p>
<p><tt>manager_included_constant</tt></p>
<p>Name of the constant that is defined within the specified driver extension class file to help preventing multiple inclusion.</p>
<p><tt>manager_class_name</tt></p>
<p>Name of the driver manager extension class.</p>
</ul>
</ul>
<h2><a name="drivers"></a><a name="206.1.3"><li>Available drivers</li></a></h2>
<p>Currently, there are several drivers being made available within the <b>Metabase</b> package but some are not completely developed. Work is in progress to finish those that are incomplete and add new drivers to support other <i>DBMS</i>.  Other drivers may be written by third party developers.</p>
<ul>
<h3><li><a href="#interbase">Interbase</a></li></h3>
<h3><li><a href="#informix">Informix</a></li></h3>
<h3><li><a href="#microsoftsqlserver">Microsoft SQL Server</a></li></h3>
<h3><li><a href="#minisql">Mini-SQL</a></li></h3>
<h3><li><a href="#mysql">MySQL</a></li></h3>
<h3><li><a href="#odbc">ODBC</a></li></h3>
<h3><li><a href="#microsoftaccess">Microsoft Access via ODBC</a></li></h3>
<h3><li><a href="#oracle">Oracle using Oracle Call Interface (oci)</a></li></h3>
<h3><li><a href="#postgresql">PostgreSQL</a></li></h3>
<h3><li><a href="#sqlite">SQLite</a></li></h3>
</ul>
<br />
<ul>
<h3><a name="interbase"></a><a name="208.2.0"><li>Interbase</li></a></h3>
<ul>
<h4><li>Driver type</li></h4>
<p><tt>ibase</tt></p>
<h4><li>Status</li></h4>
<p>Completely developed except for large objects that are supported by <i>Interbase</i> <i>DBMS</i> but its support is not yet implemented in the <b>Metabase</b> driver. Primary keys, auto-increment table fields and schema reverse engineering support functions are also not yet provided.</p>
<h4><li>Driver specific options</li></h4>
<ul>
<p><li><tt>DatabasePath</tt></li></p>
<p>Specifies the path of the directory where are located the database files that are meant to be accessed.  This path should include any ending slashes because the driver will just append the database name to it to pass the database file name to the Interbase server.</p>
<p><b>Default value:</b> empty string</p>
<p><li><tt>DatabaseExtension</tt></li></p>
<p>Specifies the extension of the database files that are meant to be accessed.  This extension is appended to the database name to pass its file name to the Interbase server.</p>
<p><b>Default value:</b> <tt>.gdb</tt></p>
<p><li><tt>DBAUser</tt></li></p>
<p>Access name of a user that connects to the server to create databases.</p>
<p><b>Default value:</b> none</p>
<p><li><tt>DBAPassword</tt></li></p>
<p>Password for user specified by the <tt>DBAUser</tt> option.</p>
<p><b>Default value:</b> none</p>
<p><li><tt>DefaultTextFieldLength</tt></li></p>
<p>Default length of text fields of unspecified length limit.</p>
<p><b>Default value:</b> <tt>4000</tt></p>
</ul>
<h4><li>Supported features</li></h4>
<ul>
<p><li><tt>Indexes</tt></li></p>
<p><li><tt>IndexSorting</tt></li></p>
<p><li><tt>SummaryFunctions</tt></li></p>
<p><li><tt>OrderByText</tt></li></p>
<p><li><tt>Sequences</tt></li></p>
<p><li><tt>GetSequenceCurrentValue</tt></li></p>
<p><li><tt>Transactions</tt></li></p>
<p><li><tt>SelectRowRanges</tt></li></p>
<p><li><tt>LOBs</tt></li></p>
</ul>
<h4><li>Notes</li></h4>
<ul>
<p><li>This driver is based on a contribution by Meir kriheli.</li></p>
<p><li>Currently, the driver relies on the Interbase server to use <i>SQL</i> dialect 3 that was introduced with Interbase 6.  Some versions of Interbase server, like the Super Server, do not seem to work by default with dialect 3.  This may lead to errors when trying to create tables using Interbase SQL data types that are only available when using this dialect version.</li></p>
<p><li>Interbase does not support per field index sorting support.  Indexes are either ascending, descending or both even when they are defined from more than one field. Currently <b>Metabase</b> Interbase driver uses the index sorting type given by the first field of the index for which it is specified the sorting type.</li></p>
<p><li>The <tt>NumberOfRows</tt> function is emulated by fetching all the rows into memory.  Avoid using it if for queries with large result sets.</li></p>
<p><li>Interbase does not provide direct support for returning result sets restricted to a given range.  Such support is emulated in the <b>Metabase</b> <tt>ibase</tt> driver.</li></p>
<p><li>Current Interbase versions do not support altering table field <tt>DEFAULT</tt> values and <tt>NOT NULL</tt> constraint.  Text fields' length may only be raised in increments defined by Interbase, so the <b>Metabase</b> Interbase does not support altering text field length yet.</li></p>
<p><li>Under Interbase, creating and dropping databases using SQL can only be implemented by executing direct queries. However, current versions of PHP execute queries by preparing them first, even when they do not have arguments to bind. This prevents query statements like <tt>CREATE DATABASE</tt> and <tt>DROP DATABASE</tt> to be executed using PHP Interbase API.  Therefore, databases have to be created manually by using <tt>isql</tt> command or a similar program before using the databases with <b>Metabase</b>.</li></p>
<p><li>Metabase creates Interbase <tt>blobs</tt> before executing a prepared queries to insert or update large object fields. If such queries fail to execute, Metabase Interbase driver class is not able to reclaim the database space allocated for the large object values because there is currently no PHP function to do so.</li></p>
</ul>
</ul>
<h3><a name="informix"></a><a name="212.2.1"><li>Informix</li></a></h3>
<ul>
<h4><li>Driver type</li></h4>
<p><tt>ifx</tt></p>
<h4><li>Status</li></h4>
<p>Completely developed except for large objects that are supported by <i>Informix</i> <i>DBMS</i> but its support is not yet implemented in the <b>Metabase</b> driver. Primary keys, auto-increment table fields and schema reverse engineering support functions are also not yet provided.</p>
<h4><li>Driver specific options</li></h4>
<ul>
<p><li><tt>Logging</tt></li></p>
<p>Specifies the mode of logging that the databases being accessed are using.  The logging mode defines the way the databases support transactions.  It also defines the way databases are created by Metabase <tt><a href="#function_MetabaseCreateDatabase">MetabaseCreateDatabase</a></tt> function.</p>
<p>The modes of logging that are supported are: <tt>Unbuffered</tt>, <tt>Buffered</tt>, <tt>ANSI</tt> and none.</p>
<ul>
<p><li><tt>Unbuffered</tt></li></p>
<p>All actions that affect a database during a transaction are logged to disk immediately as they happen.  This logging mode is slower but it is also safer in case there is a need to recover from a crash that happen during a transaction.</p>
<p><li><tt>Buffered</tt></li></p>
<p>All actions that affect a database during a transaction are logged to a buffer that is flushed to disk when it is full.  This logging mode is faster because it requires less disk access during transactions but not as safe because when crash happens during a transaction the latest actions may not be recovered if the transaction log buffer was not completely flushed to disk.</p>
<p><li><tt>ANSI</tt></li></p>
<p>All actions that affect a database during a transaction are logged to disk as with the <tt>Unbuffered</tt> logging mode.</p>
<p>When this mode of logging is specified, the function <tt><a href="#function_MetabaseCreateDatabase">MetabaseCreateDatabase</a></tt> creates a database that is <i>ANSI</i> compliant.  Please refer to the section &quot;Informix SQL Guide&quot; on the <tt>CREATE DATABASE</tt> statement to understand the full meaning of database ANSI compliance.</p>
<p>When using the <tt>ANSI</tt> logging mode, all statements are executed implicitly within a transaction.  This is completely transparent for <b>Metabase</b> applications because when transaction auto-commit mode is set to <tt>1</tt>, this driver class assures that actions are automatically committed right after each query is executed.</p>
<p><li>none</li></p>
<p>In this logging mode no database action is logged. Therefore, transactions are not supported.</p>
</ul>
<p><b>Default value:</b> none</p>
<p><li><tt>DBAUser</tt></li></p>
<p>Access name of a user that connects to the server to create databases.  Currently, if the user specified with this option is other than the user specified by the Metabase database setup option <tt>User</tt>, when a database is created this <tt>User</tt> is granted with <tt>RESOURCE</tt> access privileges, which means that he may create tables and indexes.</p>
<p><b>Default value:</b> none</p>
<p><li><tt>DBAPassword</tt></li></p>
<p>Password for user specified by the <tt>DBAUser</tt> option.</p>
<p><b>Default value:</b> none</p>
<p><li><tt>Use8ByteIntegers</tt></li></p>
<p>Indicates whether 8 byte integers should be used to declare table integer fields (<tt>INT8</tt>) and sequences (<tt>SERIAL8</tt>).  It is not recommended to set this option to <tt>1</tt> if the platform under which PHP is going to run to access a Informix server does not use at least 64 bit for integers.</p>
<p><b>Default value:</b> <tt>0</tt></p>
</ul>
<h4><li>Supported features</li></h4>
<ul>
<p><li><tt>Indexes</tt></li></p>
<p><li><tt>SummaryFunctions</tt></li></p>
<p><li><tt>OrderByText</tt></li></p>
<p><li><tt>AffectedRows</tt></li></p>
<p><li><tt>Sequences</tt></li></p>
<p><li><tt>Transactions</tt> (except when <tt>Logging</tt> mode option is not defined)</li></p>
<p><li><tt>SelectRowRanges</tt></li></p>
<p><li><tt>LOBs</tt></li></p>
</ul>
<h4><li>Notes</li></h4>
<ul>
<p><li>This driver is based on a contribution by Pierre-henri Delaval.</li></p>
<p><li>Fields of type <tt>text</tt> without specifying a limit length are declared with the Informix <tt>LVARCHAR</tt>. Currently this kind of fields is limited to 2 kilobytes in length.</li></p>
<p><li>Sequences are emulated separate tables that have a single field of the type <tt>SERIAL</tt>.  If the driver option <tt>Use8ByteIntegers</tt> is set to <tt>1</tt> fields of type <tt>SERIAL8</tt> are used instead.</li></p>
<p>The names of the tables is defined using sequence name prefixed with <tt>_sequence_</tt>.  Sequences may not start from <tt>0</tt> or less.</p>
<p><li>The <tt>NumberOfRows</tt> function is emulated by fetching all the rows into memory.  Avoid using it if for queries with large result sets.</li></p>
<p><li>When it is specified to return a given range of rows of a query result using the <tt><a href="#function_MetabaseSetSelectedRowRange">MetabaseSetSelectedRowRange</a></tt> function and the <tt>$first</tt> argument is more than <tt>0</tt>, the driver uses a scroll cursor to be able to skip any initial rows.  In this case, the Informix server implicitly creates a temporary table to store the result rows.</li></p>
<p>In any case, the <tt>FIRST</tt> clause of Informix <tt>SELECT</tt> statement is used to avoid having the server returning more rows to the client side than are needed.</p>
</ul>
</ul>
<h3><a name="microsoftsqlserver"></a><a name="217.2.2"><li>Microsoft SQL Server</li></a></h3>
<ul>
<h4><li>Driver type</li></h4>
<p><tt>mssql</tt></p>
<h4><li>Status</li></h4>
<p>Completely developed except schema reverse engineering support functions that are also not yet provided.</p>
<h4><li>Driver specific options</li></h4>
<ul>
<p><li><tt>DatabaseDevice</tt></li></p>
<p>Name of the device on which a new database should be created.</p>
<p><b>Default value:</b> <tt>&quot;DEFAULT&quot;</tt></p>
<p><li><tt>DatabaseSize</tt></li></p>
<p>Default size in megabytes with which a new database should be created.</p>
<p><b>Default value:</b> not defined</p>
</ul>
<h4><li>Supported features</li></h4>
<ul>
<p><li><tt>AffectedRows</tt></li></p>
<p><li><tt>Indexes</tt></li></p>
<p><li><tt>OrderByText</tt></li></p>
<p><li><tt>Sequences</tt></li></p>
<p><li><tt>SummaryFunctions</tt></li></p>
<p><li><tt>Transactions</tt></li></p>
<p><li><tt>SelectRowRanges</tt></li></p>
<p><li><tt>LOBs</tt></li></p>
<p><li><tt>Replace</tt></li></p>
<p><li><tt>AutoIncrement</tt></li></p>
<p><li><tt>PrimaryKey</tt></li></p>
<p><li><tt>OmitInsertKey</tt></li></p>
<p><li><tt>PatternBuild</tt></li></p>
</ul>
<h4><li>Notes</li></h4>
<ul>
<p><li>By default Microsoft SQL server does not allow inserting explicit values in auto-increment table fields. To insert a row using the next value of an auto-increment field, that field must be ommited from the <tt>INSERT</tt> query.</li></p>
<p>If an auto-increment field is used in an <tt>INSERT</tt> query right after using the <tt><a href="#function_MetabaseGetNextKey">MetabaseGetNextKey</a></tt> function, the <b>Metabase</b> driver for Microsoft SQL server rewrites the query to remove the auto-increment field from the query statement.</p>
<p>When possible, it is recommend the use of <tt>INSERT</tt> queries that omit the auto-increment field to avoid the SQL query rewriting overhead.</p>
<p>To insert rows with specific values for auto-increment fields, first it is necessary to execute the query: <tt>SET IDENTITY_INSERT some_table ON</tt>.</p>
<p><li>Until at least version 2000, the only kind of table changes that the <tt>ALTER TABLE</tt> <i>SQL</i> statement of Microsoft SQL server supports is table renaming, new field and constraint additions and column dropping.</li></p>
<p>The driver <tt>AlterTable</tt> function does not implement column renaming and other column definition changes.  In the future versions of this driver those capabilities may be emulated using other <i>SQL</i> statements to recreate the tables with a new definition.</p>
</ul>
</ul>
</ul>
<ul>
<h3><a name="minisql"></a><a name="222.2.0"><li>Mini-SQL</li></a></h3>
<ul>
<h4><li>Driver type</li></h4>
<p><tt>msql</tt></p>
<h4><li>Status</li></h4>
<p>The driver <tt>AlterTable</tt> function is not implemented because Mini-SQL does not support <tt>ALTER TABLE</tt> <i>SQL</i> command.  <tt>AlterTable</tt> function may be implemented in the future using temporary tables.  Primary keys, auto-increment table fields and schema reverse engineering support functions are also not yet provided.</p>
<h4><li>Driver specific options</li></h4>
<ul>
<p><li><tt>DefaultTextFieldLength</tt></li></p>
<p>Default length of text fields of unspecified length limit.  Fields may grow larger than the default length though.</p>
<p><b>Default value:</b> <tt>255</tt></p>
</ul>
<h4><li>Supported features</li></h4>
<ul>
<p><li><tt>Sequences</tt></li></p>
<p><li><tt>Indexes</tt></li></p>
<p><li><tt>AffectedRows</tt></li></p>
<p><li><tt>SelectRowRanges</tt></li></p>
</ul>
<h4><li>Notes</li></h4>
<ul>
<p><li>The <tt>decimal</tt> and <tt>timestamp</tt> type fields are emulated with <tt>integer</tt> fields.</li></p>
<p><li>Mini-SQL does not support field default values.  The driver will issue a warning but it may go unnoticed when creating new database table field.</li></p>
<p><li>Mini-SQL does not support returning result sets restricted to a given range.  Such support is emulated in the <b>Metabase</b> <tt>msql</tt> driver.</li></p>
<p><li>Determining if a result set value is a <tt>NULL</tt> is done by checking if it is an empty string.  However, empty strings may be valid non-<tt>NULL</tt> text column result values.  So, the <tt>ResultIsNull</tt> may return incorrect results.</li></p>
</ul>
</ul>
<h3><a name="mysql"></a><a name="226.2.1"><li>MySQL</li></a></h3>
<ul>
<h4><li>Driver type</li></h4>
<p><tt>mysql</tt></p>
<h4><li>Last tested versions</li></h4>
<p>MySQL 4.0.24 (2005-09-05)</p>
<h4><li>Status</li></h4>
<p>Completely developed.</p>
<h4><li>Driver specific options</li></h4>
<ul>
<p><li><tt>Port</tt></li></p>
<p>Number of TCP port to connect to the server.  If specified this value is appended to the name of the server to connect to separated by a colon (<tt>:</tt>).</p>
<p><b>Default value:</b> none</p>
<p><li><tt>EmulateDecimal</tt></li></p>
<p>Boolean flag that tells whether Metabase should emulate <tt>decimal</tt> data types using large integer fields. This option is meant to support old MySQL versions that did not support real decimal fields.</p>
<p><b>Default value:</b> <tt>0</tt></p>
<p><li><tt>FixedFloat</tt></li></p>
<p>Number of decimal places to use when declaring float table fields.  If this option value is other than <tt>0</tt>, float fields are declared as <tt>DOUBLE</tt> with the specified number of decimal places, otherwise the fields not are declared with any number of decimal places.  If this option is not specified, the driver class will query MySQL server and assume <tt>30</tt> as default number of decimal places if the server version is less than <tt>3.23.6</tt> or <tt>0</tt> otherwise.</p>
<p><b>Default value:</b> none</p>
<p><li><tt>DefaultTableType</tt></li></p>
<p>Name of the table type to be used when creating tables. Currently it are accepted the following types: <tt>BDB</tt>, <tt>INNODB</tt>, <tt>GEMINI</tt>, <tt>HEAP</tt>, <tt>ISAM</tt>, <tt>MERGE</tt>, <tt>MRG_MYISAM</tt>, <tt>MYISAM</tt>.</p>
<p>If <tt>UseTransaction</tt> option flag is set, the <tt>DefaultTableType</tt> must be either <tt>BDB</tt>, <tt>INNODB</tt> or <tt>GEMINI</tt>.</p>
<p>If the <tt>DefaultTableType</tt> option is not defined, not default table type is specified on table creation, if the <tt>UseTransaction</tt> option flag is not set. Otherwise the default table type is <tt>BDB</tt>.</p>
<p><b>Default value:</b> none or <tt>BDB</tt> if <tt>UseTransaction</tt> option is set</p>
<p><li><tt>UseTransactions</tt></li></p>
<p>Flag option that indicates whether the driver should support MySQL transactions.  Currently, MySQL transactions are only supported on tables of the types: <b><tt>BDB</tt> - Berkeley DB</b>, <b><tt>INNODB</tt></b> and <b><tt>GEMINI</tt></b>.</p>
<p>Transactions support using <tt>BDB</tt> tables was added to MySQL in version <tt>3.23.17</tt>.  MySQL has to be built explicitly with <b>Berkeley DB</b> external libraries to support this kind of tables.</p>
<p>MySQL does not rollback actions performed during transactions on tables that are not of type <tt>BDB</tt>. So, when the option <tt>UseTransactions</tt> is set to <tt>1</tt>, <b>Metabase</b> MySQL driver class assures that new tables are created as being of type <tt>BDB</tt> during the installation of a database.</p>
<p>Currently, MySQL requires that <tt>BDB</tt> tables have one field declared as <tt>PRIMARY KEY</tt>.  So, <b>Metabase</b> MySQL driver class also assures that a integer field named <tt>dummy_primary_key</tt> is implicitly added to the definition of the table as <tt>PRIMARY KEY</tt>, <tt>NOT NULL</tt> and <tt>AUTO_INCREMENT</tt>.  This may change when <b>Metabase</b> supports primary keys explicitly but it will completely transparent for applications that use <b>Metabase</b>.</p>
<p><tt>INNODB</tt> tables were introduced with MySQL 3.23.34a. <tt>GEMINI</tt> were introduced with NuSphere MySQL derivation. Neither <tt>INNODB</tt> nor <tt>GEMINI</tt> tables require additional primary key fields like with <tt>BDB</tt> tables.</p>
<p><b>Default value:</b> <tt>0</tt></p>
</ul>
<h4><li>Supported features</li></h4>
<ul>
<p><li><tt>Sequences</tt></li></p>
<p><li><tt>Indexes</tt></li></p>
<p><li><tt>AffectedRows</tt></li></p>
<p><li><tt>SummaryFunctions</tt></li></p>
<p><li><tt>OrderByText</tt></li></p>
<p><li><tt>GetSequenceCurrentValue</tt></li></p>
<p><li><tt>SelectRowRanges</tt></li></p>
<p><li><tt>LOBs</tt></li></p>
<p><li><tt>Transactions</tt></li></p>
<p><li><tt>Replace</tt></li></p>
<p><li><tt>PrimaryKey</tt></li></p>
<p><li><tt>AutoIncrement</tt></li></p>
<p><li><tt>OmitInsertKey</tt></li></p>
<p><li><tt>PatternBuild</tt></li></p>
</ul>
<h4><li>Notes</li></h4>
<ul>
<p><li>The <tt>decimal</tt> type fields used to be emulated with <tt>integer</tt> fields in past versions of this driver. This emulation no longer happens by default. Use the <tt>EmulateDecimal</tt> driver option to enable the decimal emulation again.</li></p>
<p><li>Unless specified an adequate default table type, MySQL does not support real transactions.  Failure to apply database schema changes may result in data loss or inconsistency.  Backup the database before attempting to apply schema changes.</li></p>
</ul>
</ul>
<h3><a name="odbc"></a><a name="230.2.2"><li>ODBC - Open Database Connectivity</li></a></h3>
<ul>
<h4><li>Driver type</li></h4>
<p><tt>odbc</tt></p>
<h4><li>Status</li></h4>
<p>The base functionality is implemented but performing actions that depends on the underlying DBMS needs to be implemented in database specific <b>Metabase</b> driver subclasses of this ODBC driver class.  Such actions include sequence creation and manipulation and database table alterations.</p>
<p><tt>CreateDatabase</tt> and <tt>DropDatabase</tt> assume that it works using <i>SQL</i> commands <tt>CREATE DATABASE</tt> and <tt>DROP DATABASE</tt>. Primary keys, auto-increment table fields and schema reverse engineering support functions are also not yet provided.</p>
<h4><li>Driver specific options</li></h4>
<ul>
<p><li><tt>DBADSN</tt></li></p>
<p>Name of the data service that database administrator has to access to create a database.</p>
<p><b>Default value:</b> empty string</p>
<p><li><tt>DBAUser</tt></li></p>
<p>Database administrator user with permissions to create databases.</p>
<p><b>Default value:</b> empty string</p>
<p><li><tt>DBAPassword</tt></li></p>
<p>Password for the user specified by the option <tt>DBAUser</tt>.</p>
<p><b>Default value:</b> empty string</p>
<p><li><tt>DefaultTextFieldLength</tt></li></p>
<p>Default length of text fields of unspecified length limit when the underlying DBMS does not have a specific data type for this kind of text fields and <tt>odbc</tt> driver needs to implement this using <tt>VARCHAR</tt> fields.</p>
<p><b>Default value:</b> 255</p>
<p><li><tt>UseTransactions</tt></li></p>
<p>Boolean option that indicates whether the underlying DBMS supports transactions.</p>
<p><b>Default value:</b> 0</p>
<p><li><tt>UseIndexes</tt></li></p>
<p>Boolean option that indicates whether the underlying DBMS supports index creation.</p>
<p><b>Default value:</b> 0</p>
<p><li><tt>UseDefaultValues</tt></li></p>
<p>Boolean option that indicates whether the underlying DBMS supports transactions the specification of default values for table fields.</p>
<p><b>Default value:</b> 1</p>
<p><li><tt>UseDecimalScale</tt></li></p>
<p>Boolean option that indicates whether the underlying DBMS supports the specification of the number of places for the scale of decimal values.  If this option is <tt>0</tt>, the <b>Metabase</b> <tt>odbc</tt> driver assumes that ODBC <tt>DECIMAL</tt> data type works with scale <tt>0</tt> and will perform necessary value conversions to send and retrieve decimal values to interchange with the database.</p>
<p><b>Default value:</b> 1</p>
<p><li><tt>EscapeBackslashes</tt></li></p>
<p>Boolean option that indicates whether text values with backslash characters (<tt>\</tt>) need to be escaped with another backslash character (<tt>\\</tt>). The ANSI standard does not require escaping of backslash characters, but some ODBC drivers do not take care of that, so this option needs to be enabled.</p>
<p><b>Default value:</b> 0</p>
</ul>
<h4><li>Supported features</li></h4>
<ul>
<p><li><tt>AffectedRows</tt></li></p>
<p><li><tt>SelectRowRanges</tt></li></p>
<p><li><tt>Transactions</tt>, if the <tt>UseTransactions</tt> option is set to <tt>1</tt>.</li></p>
<p><li><tt>LOBs</tt>, if the underlying <i>DBMS</i> supports at least the ODBC type <tt>LONGVARBINARY</tt>.</li></p>
</ul>
<h4><li>Notes</li></h4>
<ul>
<p><li>The driver will attempt to map the <b>Metabase</b> data types to those supported by the underlying DBMS.  When it is not possible to find a suitable type to using hard-coded data type mappings.  This is the case when using a version of PHP less than 4.0.</li></p>
<p><li>The <tt>database_name</tt> driver object variable is used as current <tt>DSN</tt>.</li></p>
<p><li>Column numbers for fetching result start from <tt>0</tt> not from <tt>1</tt>.</li></p>
<p><li>The <tt>NumberOfRows</tt> function is emulated by fetching all the rows into memory.  Avoid using it if for queries with large result sets.</li></p>
<p><li>ODBC does not provide direct support for returning result sets restricted to a given range.  Such support is emulated in the <b>Metabase</b> <tt>odbc</tt> driver.</li></p>
</ul>
</ul>
<h3><a name="microsoftaccess"></a><a name="234.2.3"><li>Microsoft Access via ODBC</li></a></h3>
<ul>
<h4><li>Driver type</li></h4>
<p><tt>odbc-msaccess</tt></p>
<h4><li>Status</li></h4>
<p>This driver extends the generic <tt>odbc</tt> driver redefining some operations and default values with first hand information about the way Microsoft Access databases work and what features are supported.</p>
<p>Most considerations made about the generic <tt>odbc</tt> driver still apply to the Microsoft Access driver. However certain features are improved.</p>
<h4><li>Driver specific options</li></h4>
<ul>
<p><li><tt>CLOBType</tt></li></p>
<p>Name of the native data type to use for character LOBs.</p>
<p><b>Default value:</b> &quot;MEMO&quot;</p>
<p><li><tt>BLOBType</tt></li></p>
<p>Name of the native data type to use for binary LOBs.</p>
<p><b>Default value:</b> &quot;IMAGE&quot;</p>
</ul>
<h4><li>Supported features</li></h4>
<ul>
<p><li><tt>AffectedRows</tt></li></p>
<p><li><tt>SelectRowRanges</tt></li></p>
<p><li><tt>Indexes</tt> unless <tt>UseIndexes</tt> option is set to <tt>0</tt>.</li></p>
<p><li><tt>Transactions</tt> unless <tt>UseTransactions</tt> option is set to <tt>0</tt>.</li></p>
<p><li><tt>Replace</tt> unless <tt>UseTransactions</tt> option is set to <tt>0</tt>.</li></p>
<p><li><tt>Sequences</tt></li></p>
<p><li><tt>GetSequenceCurrentValue</tt></li></p>
<p><li><tt>LOBs</tt></li></p>
<p><li><tt>PatternBuild</tt></li></p>
</ul>
<h4><li>Notes</li></h4>
<ul>
<p><li>This driver is based on a contribution by Svemir Brkic.</li></p>
<p><li>Database creation is not supported as it is not possible to create a database via SQL.</li></p>
<p><li>Indexes are supported. The driver enables index management support unless told otherwise setting the <tt>UseIndexes</tt> option to <tt>0</tt>.</li></p>
<p><li>Sequences are also supported using auto-incremented fields in separate tables. However, sequences may only work with the latest versions of Microsoft Jet database engine that support fetching the last inserted value using the <tt>@@IDENTITY</tt> value.</li></p>
<p><li>Transactions are also supported in the latest versions of Microsoft Jet database engine. The driver enables transaction support unless told otherwise by setting the <tt>UseTransactions</tt> option to <tt>0</tt>.</li></p>
<p><li>The specification of field default values at table creation time is not supported by the current versions of Microsoft Access. In the case that future versions support default values it may be enabled setting the <tt>UseDefaultValues</tt> option to <tt>1</tt>.</li></p>
<p><li>If the <tt>UseDecimalScale</tt> option is set to <tt>1</tt>, the driver will use <tt>INT</tt> fields for decimal table columns. Otherwise, it will use <tt>CURRENCY</tt> type that only supports a fixed number of 4 decimal places.</li></p>
<p><li>LOB fields are supported. By default, character LOBs are stored in <tt>MEMO</tt> fields and binary LOBs are stored in <tt>IMAGE</tt> fields. These types may be overriden with the options <tt>CLOBType</tt> and <tt>BLOBType</tt> respectively.</li></p>
</ul>
</ul>
<h3><a name="oracle"></a><a name="238.2.4"><li>Oracle using Oracle Call Interface (oci)</li></a></h3>
<ul>
<h4><li>Driver type</li></h4>
<p><tt>oci</tt></p>
<h4><li>Last tested versions</li></h4>
<p>Oracle9i 9.0.2.4.0 (2005-09-04)</p>
<h4><li>Status</li></h4>
<p>The driver <tt>AlterTable</tt> function is not able rename fields because it is not supported by Oracle at least until version 9.0.2.  It implements the ability to drop columns but in earlier versions of Oracle that was not supported.  The <tt>AlterTable</tt> function does not verify the server version when this function with the <tt>$check</tt> argument set to determine whether dropping columns is supported. Schema reverse engineering support functions are also not yet provided.</p>
<p>The driver does not dispose the data of the previously fetched rows.  In the future there will be an option for random access to result set row data, that unless it is specified, the data of rows before the current being fetched is disposed to save memory on queries that return large row sets.</p>
<h4><li>Driver specific options</li></h4>
<ul>
<p><li><tt>SID</tt></li></p>
<p>Service identifier of the database instance that is meant to be accessed.</p>
<p><b>Default value:</b> value of the environment variable <tt>ORACLE_SID</tt></p>
<p><li><tt>HOME</tt></li></p>
<p>Home directory path when Oracle is installed if it is running in the local machine.</p>
<p><b>Default value:</b>  value of the environment variable <tt>ORACLE_HOME</tt></p>
<p><li><tt>DefaultTextFieldLength</tt></li></p>
<p>Default length of text fields of unspecified length limit.  Fields may not grow larger than the length by this option.</p>
<p><b>Default value:</b> 4000</p>
<p><li><tt>DBAUser</tt></li></p>
<p>Access name of a user with the necessary permissions to execute the commands necessary in the function <tt>CreateDatabase</tt>.  It should be <tt>SYS</tt> or any other with equivalent privileges.</p>
<p><b>Default value:</b> none</p>
<p><li><tt>DBAPassword</tt></li></p>
<p>Password for user specified by the <tt>DBAUser</tt> option.</p>
<p><b>Default value:</b> none</p>
<p><li><tt>DefaultTablespace</tt></li></p>
<p>Name of the default tablespace where will be located the user schema that is implicitly created for the database user in the <tt>CreateDatabase</tt> function.  If this option is not specified, Oracle will use the <tt>SYSTEM</tt> tablespace as default tablespace.</p>
<p><b>Default value:</b> none</p>
</ul>
<h4><li>Supported features</li></h4>
<ul>
<p><li><tt>Indexes</tt></li></p>
<p><li><tt>SummaryFunctions</tt></li></p>
<p><li><tt>OrderByText</tt></li></p>
<p><li><tt>AffectedRows</tt></li></p>
<p><li><tt>Sequences</tt></li></p>
<p><li><tt>Transactions</tt></li></p>
<p><li><tt>SelectRowRanges</tt></li></p>
<p><li><tt>LOBs</tt></li></p>
<p><li><tt>Replace</tt></li></p>
<p><li><tt>AutoIncrement</tt></li></p>
<p><li><tt>PrimaryKey</tt></li></p>
<p><li><tt>OmitInsertKey</tt></li></p>
<p><li><tt>PatternBuild</tt></li></p>
</ul>
<h4><li>Notes</li></h4>
<ul>
<p><li>The concept of creation of a database in Oracle is a little different from other <i>DBMS</i>.  While in others a database is a logical space on which the database objects are stored, in a Oracle database there may be many distinct logical spaces.  The concept that resembles more to a single space database in Oracle is a user schema.</li></p>
<p>The <b>Metabase</b> <tt>oci</tt> driver implements the function <tt>CreateDatabase</tt> by creating a user with the necessary grants to execute the usual operations that <b>Metabase</b> applications need.  A logical database created this way is confined to the user schema space.</p>
<p>The <tt>User</tt> and <tt>Password</tt> options specified when calling the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> are used to create a new user schema.  Therefore, the specified user must not exist when calling the <tt>CreateDatabase</tt> function.  The database name argument is ignored by this function.</p>
<p>The <tt>DropDatabase</tt> function is implemented by dropping the specified user and, consequently, any objects located in the respective schema space.  This user and the respective schema space should not be used for any purpose other than accessing it using the <b>Metabase</b> functions.</p>
<p><li>Text fields with unspecified length limit are created as <tt>VARCHAR</tt> with an optional limit that may not exceed 4000 characters.</li></p>
<p><li><tt>date</tt> fields are emulated with date fields with time set to <tt>00:00:00</tt>.  <tt>time</tt> fields are emulated with date fields with the day set to <tt>0001-01-01</tt>.</li></p>
<p><li>The <tt>NumberOfRows</tt> function is emulated by fetching all the rows into memory.  Avoid using it if for queries with large result sets.</li></p>
<p><li>Oracle does not provide direct support for returning result sets restricted to a given range.  Such support is emulated in the <b>Metabase</b> <tt>oci</tt> driver.</li></p>
<p><li>Storing data in large object fields has to be done in two phases: first the fields are initialized using a <tt>INSERT</tt> or <tt>UPDATE</tt> query that sets the fields to an empty value, then the data values are uploaded to the large objects returned by reference from the executed queries.</li></p>
<p>Besides the fact that only <tt>INSERT</tt> and <tt>UPDATE</tt> queries are supported to upload large object data values, only <tt>UPDATE</tt> queries that affect only one row will set the large object fields correctly.</p>
<p><li>Despite the <b>Metabase</b> <tt>oci</tt> driver sets the environment variable <tt>ORACLE_HOME</tt> to the value of <tt>HOME</tt> driver specific option, it is necessary to also set the <tt>ORACLE_HOME</tt> prior to the execution of a PHP script.</li></p>
<p>When that variable is not set, some versions of the PHP <tt>oci</tt> extension may either crash with a segmentation fault error, or fail to connect to an Oracle database usually returning the error <tt>ORA-03117: two-task save area overflow</tt>.</p>
<p>When PHP is run from a Web server, the <tt>ORACLE_HOME</tt> environment variable may be set before executing the script that starts the Web server, or within the Web server configuration, depending on the Web server that you are using.</p>
<p><li>Oracle does not support table auto-incremented key fields natively. This driver emulates auto-incremented key fields using sequences.</li></p>
<p>The auto-increment emulation sequences are implicitly created by the <tt><a href="#function_MetabaseCreateDetailedTable">MetabaseCreateDetailedTable</a></tt> or <tt><a href="#function_MetabaseAlterTable">MetabaseAlterTable</a></tt>. The name of the sequence associated to a table with an auto-increment field is the prefix <tt>auto_increment_</tt> followed by the table name.</p>
<p>A trigger is also added to a table with an auto-increment field to automatically set the field with the next sequence value when a new row is inserted and the auto-increment field is omitted or set to <tt>NULL</tt>. The name of the trigger is the table name followed by the suffix <tt>_key_insert</tt>.</p>
<p>Dropping tables with auto-incremented fields must be done using the <tt><a href="#function_MetabaseDropDetailedTable">MetabaseDropDetailedTable</a></tt> to assure that the associated sequences and triggers are also dropped.</p>
</ul>
</ul>
<h3><a name="postgresql"></a><a name="242.2.5"><li>PostgreSQL</li></a></h3>
<ul>
<h4><li>Driver type</li></h4>
<p><tt>pgsql</tt></p>
<h4><li>Last tested versions</li></h4>
<p>PostgreSQL 7.3.10 (2005-09-04)</p>
<h4><li>Status</li></h4>
<p>The driver <tt>AlterTable</tt> function can change the table field attributes such as the length, but this is only supported by PostgreSQL 8 server. Adding table columns is also implemented, but it is only supported by PostgreSQL 7.3 server. Schema reverse engineering support functions are also not yet provided.</p>
<h4><li>Driver specific options</li></h4>
<ul>
<p><li><tt>EmulateDecimal</tt></li></p>
<p>Boolean flag that tells whether Metabase should emulate <tt>decimal</tt> data types using large integer fields. This option is meant to support old PostgreSQL versions that did not support real decimal fields.</p>
<p><b>Default value:</b> <tt>0</tt></p>
<p><li><tt>Port</tt></li></p>
<p>Number of TCP port to connect to the server.</p>
<p><b>Default value:</b> empty string</p>
</ul>
<h4><li>Supported features</li></h4>
<ul>
<p><li><tt>Sequences</tt></li></p>
<p><li><tt>Indexes</tt></li></p>
<p><li><tt>AffectedRows</tt></li></p>
<p><li><tt>SummaryFunctions</tt></li></p>
<p><li><tt>OrderByText</tt></li></p>
<p><li><tt>Transactions</tt></li></p>
<p><li><tt>GetSequenceCurrentValue</tt></li></p>
<p><li><tt>SelectRowRanges</tt></li></p>
<p><li><tt>LOBs</tt></li></p>
<p><li><tt>Replace</tt></li></p>
<p><li><tt>AutoIncrement</tt></li></p>
<p><li><tt>PrimaryKey</tt></li></p>
<p><li><tt>OmitInsertKey</tt></li></p>
<p><li><tt>PatternBuild</tt></li></p>
</ul>
<h4><li>Notes</li></h4>
<ul>
<p><li>Creation of new databases is based on database <tt>template1</tt>.</li></p>
<p><li>The <tt>decimal</tt> type fields are emulated with <tt>integer</tt> fields.</li></p>
<p><li>The <tt>decimal</tt> type fields used to be emulated with <tt>integer</tt> fields in past versions of this driver. This emulation no longer happens by default. Use the <tt>EmulateDecimal</tt> driver option to enable the decimal emulation again.</li></p>
<p><li>PostgreSQL stores large objects in files managed by the server. Tables with large object fields only store identifiers pointing to those files. If you delete or update rows of those tables, the actual large object files are not deleted from the server file system. Therefore you may need to reclaim large object field space by deleting those files manually.</li></p>
<p><li>PostgreSQL supports table auto-incremented keys using fields of type <tt>SERIAL</tt>. However, since early PostgreSQL versions did not support this kind of fields, this driver emulates auto-incremented key fields using sequences.</li></p>
<p>The auto-increment emulation sequences are implicitly created by the <tt><a href="#function_MetabaseCreateDetailedTable">MetabaseCreateDetailedTable</a></tt> or <tt><a href="#function_MetabaseAlterTable">MetabaseAlterTable</a></tt>. The name of the sequence associated to a table with an auto-increment field is the prefix <tt>_auto_increment_</tt> followed by the table name.</p>
<p>Dropping tables with auto-incremented fields must be done using the <tt><a href="#function_MetabaseDropDetailedTable">MetabaseDropDetailedTable</a></tt> to assure that the associated sequences are also dropped.</p>
</ul>
</ul>
<h3><a name="sqlite"></a><a name="246.2.6"><li>SQLite</li></a></h3>
<ul>
<h4><li>Driver type</li></h4>
<p><tt>sqlite</tt></p>
<h4><li>Status</li></h4>
<p>The driver <tt>AlterTable</tt> function only implements table renaming and field adding. Those types of changes require using SQLite 3 libraries. Prior versions do not support any kind of table schema changes.</p>
<h4><li>Driver specific options</li></h4>
<ul>
<p><li><tt>AccessMode</tt></li></p>
<p>Specify the database file access mode which determines the permissions that the database file will have when it is created. If the value starts with <tt>0</tt>, the permissions value is interpreted as an octal value.</p>
<p><b>Default value:</b> <tt>0664</tt></p>
<p><li><tt>DatabasePath</tt></li></p>
<p>Specifies the path of the directory where are located the database files that are meant to be accessed.  This path should include any ending slashes because the driver will just append the database name to open its file.</p>
<p><b>Default value:</b> empty string</p>
<p><li><tt>DatabaseExtension</tt></li></p>
<p>Specifies the extension of the database files that are meant to be accessed.  This extension is appended to the database name to to open its file.</p>
<p><b>Default value:</b> <tt>.db</tt></p>
</ul>
<h4><li>Supported features</li></h4>
<ul>
<p><li><tt>Sequences</tt></li></p>
<p><li><tt>Indexes</tt></li></p>
<p><li><tt>AffectedRows</tt></li></p>
<p><li><tt>SummaryFunctions</tt></li></p>
<p><li><tt>OrderByText</tt></li></p>
<p><li><tt>Transactions</tt></li></p>
<p><li><tt>GetSequenceCurrentValue</tt></li></p>
<p><li><tt>SelectRowRanges</tt></li></p>
<p><li><tt>Replace</tt></li></p>
<p><li><tt>Transactions</tt></li></p>
<p><li><tt>LOBs</tt></li></p>
<p><li><tt>AutoIncrement</tt></li></p>
<p><li><tt>PrimaryKey</tt></li></p>
<p><li><tt>OmitInsertKey</tt></li></p>
<p><li><tt>PatternBuild</tt> if SQLite library version is at least 3.1.0.</li></p>
</ul>
<h4><li>Notes</li></h4>
<ul>
<p><li><a href="http://www.sqlite.org/">SQLite</a> is an API to create and manage flat file databases using SQL. It does not require a database server because the SQLite API accesses to the database files directly.</li></p>
<p><li>This driver is based on a contribution originally made by Jeroen Derks. It was meant to work with the <a href="http://sourceforge.net/projects/sqlite-php/">SQLite API for PHP</a> which was discontinued.</li></p>
<p><li>John Walton updated this driver to make it work with the official PHP SQLite extension that is distributed with PHP 5. That extension is also available for PHP 4 in the <a href="http://pecl.php.net/package/SQLite">PECL PHP extensions repository</a>.</li></p>
<p><li>SQLite data is typeless. This means that it stores everything as text that is interpreted as data of given types in data type specific operations.</li></p>
<p><li>Changes to a database schema may not be visible to existing database connections established before such changes were performed. If you change a database schema, make sure all connections to the same database and closed and reopened, so the schema changes are visible to all connections.</li></p>
</ul>
</ul>
</ul>
</ul>
<hr />
<h1><a name="250.0">DBMS specific drivers conformance test suite</a></h1>
<ul>
<h2><a name="251.1.0"><li>Software quality assurance</li></a></h2>
<p>Software development is an engineering discipline that has as goal the development of products that consist of computer programs and data.  Software products are meant to be used to perform well-defined computer tasks.</p>
<p>Like in other engineering disciplines, the quality of a software product can only be certified if it can be demonstrated that the software works according to its product specification.</p>
<p>Software quality certification is an important issue because it inspires the trust of the users that rely on the products to achieve their goals with the software that they intend to use.</p>
<p>Users that trust on the software they use are usually more satisfied with their software product choice.  Satisfied users often contribute voluntarily to the dissemination of the products among user communities with the same interests.  Usually this leads to the increase of the user base.  The increase of product user base often fosters further product development and consequently further user satisfaction.</p>
<h2><a name="251.1.1"><li>Metabase software quality certification methods</li></a></h2>
<p>For a complex software product like <b>Metabase</b>, it is not easy to demonstrate that it works according to its specification under all possible circumstances that it may be used.  However, it is possible specify a set of tests that demonstrate that the package works as specified.</p>
<p>As part of the development of <b>Metabase</b>, it was specified a set of tests to verify the conformance of the package in general and the <i>DBMS</i> specific drivers in particular.</p>
<p>Each of the specified tests produces a series of results.  The testing method that is used compares the results that are obtained with the results that are expected.  If they do not match, the test failed and there is a conformance problem with either <b>Metabase</b> programming interface or with the implementation of the <i>DBMS</i> specific driver that was used in the test.</p>
<p>Failed tests are a very good reason to send bug reports, so the developers that are in charge take some action to trace the cause and eventually fix the bugs that lead to the test failures.</p>
<p>When new features are added, a correspondent number of tests should be added to also verify the conformance of such features.</p>
<p>The same set of tests should be repeated using different <i>DBMS</i> specific drivers.  They also should be repeated before making each new release of the package, even if the features that they test were not changed.  It may happen that the addition or change of some features may accidentally break other features that used to be working.  This procedure of repeating previously successful tests is called <i>regression testing</i>.</p>
<h2><a name="251.1.2"><li><b>Metabase</b> test suite</li></a></h2>
<p><b>Metabase</b> test suite is currently implemented as a single script that implements several different tests.  The test suite script is named <tt>driver_test.php</tt>.</p>
<p>The current set of tests is <i>DBMS</i> independent.  This means that they do not verify aspects that are specific only to each of the supported <i>DBMS</i>, but rather features that are expected to work equally with all <i>DBMS</i> specific drivers that support them.</p>
<p>The test suite script performs tests with only one <i>DBMS</i> at once.  A configuration script named <tt>driver_test_configuration.php</tt> should be edited to choose the driver to use in the tests as well to choose the values of some <i>DBMS</i> specific parameters in the <tt>$driver_arguments</tt> array as they are defined for the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The sample configuration script pre-defines option values for each of the supported <i>DBMS</i> specific drivers, but you may need to adjust those values to make it work with your setup.</p>
<p>The test script also installs a test database named <tt>driver_test</tt>.  You should adjust the <tt>$database_variables</tt> array in the configuration script to change the test database name changing the <tt>name</tt> array entry or tell the script to not create the database but rather use a previously created database changing the <tt>create</tt> entry to <tt>&quot;0&quot;</tt>.</p>
<h2><a name="251.1.3"><li>Supported tests types</li></a></h2>
<p>The <b>Metabase</b> test suite could perform other tests besides the ones that are currently implemented.  More tests will be included in a future release.</p>
<p>With some <i>DBMS</i> specific drivers there are tests that are deliberately skipped because the features being tested are not supported by the driver.  The test script will not denote those tests as failures but it will notice that the respective features are not supported by the driver.</p>
<p>These are tests that are currently implemented:</p>
<ul>
<h3><a name="252.2.0"><li>Storing and retrieving different data types</li></a></h3>
<p>This test inserts several rows in a table that has fields that use all data types supported by <b>Metabase</b>.  Then it selects the same rows to verify if the fetched data matches the data that was inserted.</p>
<h3><a name="252.2.1"><li>Retrieving query result data using bulk fetching functions</li></a></h3>
<p>This test inserts several rows in a table that has fields that use all data types supported by <b>Metabase</b>.  Then it selects the same rows using functions that execute the query and retrieve the whole data in a single call to verify if the fetched data matches the data that was inserted.</p>
<h3><a name="252.2.2"><li>Prepared queries</li></a></h3>
<p>This test inserts rows with constant text values that have question marks and quote characters to verify if the driver class is able to distinguish these characters from real prepared query value place holders.</p>
<h3><a name="252.2.3"><li>Query result set metadata retrieval</li></a></h3>
<p>This test performs a <tt>SELECT</tt> query and verifies if the the number and the names of the columns of the returned result set correspond to what is expected.</p>
<h3><a name="252.2.4"><li>Storing and retrieving NULL values</li></a></h3>
<p>This test inserts repeatedly a single row with a column with different text values and then a real <tt>NULL</tt> value.  Then it selects the same row to verify whether the inserted row column contains a <tt>NULL</tt> as expected.  This test also verifies if the driver <tt>EndOfResult</tt> function returns correct values.</p>
<h3><a name="252.2.5"><li>Escaping text values with special characters</li></a></h3>
<p>This test inserts rows with a text column with character sequences that usually need to be correctly escaped with the driver classes' function <tt>GetTextFieldValue</tt>.  Then it selects the inserted rows to verify if the column contains the correct text values.  This test also verifies if the driver <tt>EndOfResult</tt> function returns correct values.</p>
<h3><a name="252.2.6"><li>Selecting query result row ranges</li></a></h3>
<p>This test is similar to the previous, but instead of selecting all rows in a single query, it selects different ranges of rows by executing the same query several times.</p>
<h3><a name="252.2.7"><li>Sequences</li></a></h3>
<p>This test creates a sequence several times with different start values.  It verifies if the function to retrieve the next sequence value returns the correct values.</p>
<h3><a name="252.2.8"><li>Count of rows affected by a query</li></a></h3>
<p>This test executes INSERT, UPDATE and DELETE queries.  Then verifies if the function to retrieve the number of affected rows, matches the expected number of rows changed in the table.</p>
<h3><a name="252.2.9"><li>Transactions</li></a></h3>
<p>This test starts a transaction using the function to disable auto committing.  Then it inserts a table row and rolls back the transaction to verify if the insertion of the row was effectively canceled.  Then it inserts the table row again and commits the transaction to verify if the row was effectively inserted. Finally, it deletes the inserted row and implicitly commits and ends the transaction disabling auto committing to verify if the inserted row was effectively deleted.</p>
<h3><a name="252.2.10"><li>Updating a table with the SQL REPLACE query</li></a></h3>
<p>This test inserts a row in a table and updates the same row with the <i>SQL</i> <tt>REPLACE</tt> query and verify that the row data was properly inserted and updated.</p>
<h3><a name="252.2.11"><li>Storing and retrieving data in large object fields</li></a></h3>
<p>This test stores character and binary data in large object fields and retrieves those field values to verify whether they contain what was stored.</p>
<h3><a name="252.2.12"><li>Storing and retrieving data in large object fields from and to files</li></a></h3>
<p>This test stores character and binary data read from files in large object fields and retrieves those field values into the  same files to verify whether they contain what was stored.</p>
<h3><a name="252.2.13"><li>Storing and retrieving NULL values in large object fields</li></a></h3>
<p>This test inserts <tt>NULL</tt> values in large object fields and then verifies whether they are stored correctly.</p>
<h3><a name="252.2.14"><li>Retrieving auto-increment keys in direct queries</li></a></h3>
<p>This test inserts rows in a table with auto-incremented key fields using direct queries and then verifies whether the information in the table rows matches the inserted values of the auto-increment key field and of other fields.</p>
<h3><a name="252.2.15"><li>Retrieving auto-increment keys in prepared queries</li></a></h3>
<p>This test inserts rows in a table with auto-incremented key fields using prepared queries and then verifies whether the information in the table rows matches the inserted values of the auto-increment key field and of other fields.</p>
<h3><a name="252.2.16"><li>Match patterns</li></a></h3>
<p>This test inserts several rows in a table and executes different queries to verify whether the inserted text values match the expected patterns.</p>
</ul>
<h2><a name="252.1.4"><li>Known conformance failure issues</li></a></h2>
<p>The current <b>Metabase</b> release does not have any problems that are known to be due to bugs in <b>Metabase</b> programming interface or <i>DBMS</i> specific drivers.  However, there are some issues that make the conformance tests fail due to known problems in PHP or some releases of certain <i>DBMS</i>.</p>
<ul>
<h3><a name="253.2.0"><li>Interbase</li></a></h3>
<p>In some versions of Interbase, the database server may not be able to start or commit transactions causing errors or entering in deadlock.  These problems are not due to problems with PHP or this Metabase driver, as they seem to be caused by problems in the communication between Interbase client libraries and the server.  These problems may lead driver transactions test fail with errors, thus making the driver test script to exit.</p>
<h3><a name="253.2.1"><li>Informix</li></a></h3>
<p>At least until the current version of PHP there is no way to determine with certainty whether a result value is <tt>NULL</tt>.</p>
<p><b>Metabase</b> <tt>ifx</tt> driver checks the result values against the string text <tt>NULL</tt> which could mean either that it is a real <tt>NULL</tt> value or it is a text value with a string with the letters of <tt>NULL</tt>.  This fact makes the <tt>nulls</tt> driver conformance test fail.</p>
<h3><a name="253.2.2"><li>Mini-SQL</li></a></h3>
<p>At least until the current version of PHP there is no way to determine with certainty whether a result value is <tt>NULL</tt>.</p>
<p><b>Metabase</b> <tt>msql</tt> driver checks the result values against an empty string which could mean either that it is a real <tt>NULL</tt> value or it is a text value with a real empty string.  This fact makes the <tt>nulls</tt> driver conformance test fail.</p>
<h3><a name="253.2.3"><li>MySQL</li></a></h3>
<p>Sequences are emulated by the MySQL driver using tables with a single column defined with the <tt>AUTO_INCREMENT</tt> attribute. The initial value of a sequence emulated this way is set by inserting one row in the table with the sequence start value minus <tt>1</tt> in the auto incrementing column.</p>
<p>Apparently, since MySQL 3.23 release auto-incremented columns with values that are negative are turned into into a very large positive numbers despite the column is declared as signed integer.</p>
<p>This problem was reported to MySQL development team but they do not understand this as a bug, despite there was no such problem in earlier MySQL releases.  This means that they are not willing to fix MySQL behavior to make it work consistently with the declaration of the column type, i.e., auto-incremented values be handled as signed or unsigned depending on the type of integer declared for the respective column.</p>
<p>This problem only affects sequences that start with <tt>0</tt> or less.  Use sequences that start from <tt>1</tt> or more to avoid the problem.</p>
<p>At the time of writing of this document the currently available version of MySQL (<tt>3.23.23</tt>) is known to not work well with <tt>BDB</tt> tables.  Specifically selecting data from <tt>BDB</tt> using the <tt>ORDER BY</tt> clause is known to fail.  <tt>BDB</tt> tables are created by <b>Metabase</b> MySQL driver class to be able to support transactions.</p>
<h3><a name="253.2.4"><li>ODBC</li></a></h3>
<p>At least until the current version of PHP (4.3) there is no way to determine whether a result value is <tt>NULL</tt>. PHP ODBC functions return an empty string where a <tt>NULL</tt> result value is expected. This fact makes the driver conformance tests <tt>nulls</tt> and <tt>lobnulls</tt> fail. The bug in PHP was reported and it may be fixed soon.</p>
<h3><a name="253.2.5"><li>PostgreSQL</li></a></h3>
<p>The <b>Metabase</b> PostgreSQL driver sets the <tt>PG_DATESTYLE</tt> environment variable to assure that date column values are returned by PostgreSQL database queries formatted with the <i>ISO 8601</i> standard (<tt>YYYY-MM-DD</tt>).</p>
<p>Apparently, under at least release <tt>PHP 4 RC1</tt>, when a connection to PostgreSQL server is established for a second time in the same script execution, the <tt>PG_DATESTYLE</tt> environment variable is corrupted by PHP <tt>setenv</tt> function, making subsequent PostgreSQL result fetching calls return dates formatted in the PostgreSQL default date format, which usually is not the format defined by <i>ISO 8601</i> standard.  This makes the first two tests fail when using <tt>PHP RC1</tt>.</p>
<p>The problem was reported and fixed by to the PHP development team before <tt>PHP 4.0.0</tt> was released.  It does not seem to exist in PHP 3 releases.</p>
<h3><a name="253.2.6"><li>Oracle</li></a></h3>
<p>Current Oracle DBMS treat empty strings as <tt>NULL</tt> when inserting or updating data in table columns of text.  This behavior may change in the future but currently it makes the <b>Metabase</b> <tt>nulls</tt> driver conformance test fail.</p>
</ul>
</ul>
<hr />
<h1><a name="253.0">Schema description parser</a></h1>
<ul>
<p><b>Metabase</b> schema description parser is class that is able to parse a custom data format that is used to describe database schemas in a <i>DBMS</i> independent manner.</p>
<h2><a name="254.1.0"><li>Schema description</li></a></h2>
<ul>
<h3><a name="255.2.0"><li>Introduction to <i>XML</i></li></a></h3>
<p>The schema description format is based on <i>XML</i> (<i>eXtensible Markup Language</i>).  For those that are not familiar with it, <i>XML</i> is standard that specifies rules to define abstract data formats based on tagged text.</p>
<p>Like <i>HTML</i> (<i>HyperText Markup Language</i>), <i>XML</i> is also based on <i>SGML</i> (<i>Standard Generalized Markup Language</i>).  <i>SGML</i> defines rules to structure data using special text tags.</p>
<p><i>SGML</i> tags may be used to delimit data sections.  Section begin tags are of the form <tt>&lt;name attributes... &gt;</tt> and end tags are of the form <tt>&lt;/name&gt;</tt>. <tt>name</tt> is the name of the tag and <tt>attributes</tt> is a set of zero or more pairs of attribute names and the values associated with the respective tag.</p>
<p><i>XML</i> is a little stricter in the way tags may be used. While with many <i>SGML</i> formats some end tags are optional, in <i>XML</i> end tags are always required.  Also, when tag attributes are used, attribute values must be specified always between quotes.  These <i>XML</i> requirements are usually known as <b>well-formedness</b>.</p>
<p>Another important detail about XML strictness is that tag names and attributes are case sensitive.  This means that tags in upper case are distinct from tags in lower case.</p>
<h3><a name="255.2.1"><li>Schema description format and <i>XML</i></li></a></h3>
<p>Unlike a common (but mistaken) belief, <i>XML</i> is not meant just for describing data in documents that are meant to be displayed or printed.  <i>XML</i> is a standard that defines rules for describing abstract data may be used to for any purpose.</p>
<p>Even though it may be used to schemas that may be displayed or printed, <b>Metabase</b> schema description format is meant to provide a way for developers to design their database schemas using a <i>DBMS</i> independent file format.  Using this format, developers may describe relations and properties of tables, field, indexes, sequences, etc..</p>
<p>This format uses just a subset of the <i>XML</i> known as <i>SML</i> (<i>Simplified Markup Language</i>).  <i>SML</i> formats complies with the same rules as any <i>XML</i> format but it does not use all its possibilities to make it simpler for users to write and understand the data.  For instance, files written on <i>SML</i> do not use any tag attributes.</p>
<p><b>Metabase</b> schema description format is also simpler to edit by hand because tags and constant data values should always be in lower case to save the user from holding frequently the keyboard shift key.</p>
<h3><a name="schema_description"></a><a name="255.2.2"><li>Schema description data structure</li></a></h3>
<p>The <b>Metabase</b> schema description format lets the developers describe a set of database schema objects following the database objects hierarchy.  This means that a database may contain tables and sequence objects, tables may contain fields and index objects and all these objects have their own attributes.</p>
<p>The definition of each database schema object contained within the begin and end tags of the respective container object. Therefore, the definition of each table and sequence has to be specified between the main database begin and end tags. Likewise, the definition of fields and indexes has to be specified between the respective table begin and end tags.</p>
<p>The properties of each schema object are also defined between the respective begin and end tags.  The values of each property are also defined between the respective property being and end tags.</p>
<p>The values of the properties are subject of validation according to the type of each property and the context within which they are being defined.</p>
<p>Some properties define names of database schema objects.  There are names that are accepted as valid for some <i>DBMS</i> that are not accepted by other <i>DBMS</i>.  <b>Metabase</b> schema parser may optionally fail if such names are used to reduce the potential problems when using the same <b>Metabase</b> based application with different <i>DBMS</i>.</p>
<ul>
<p>The schema object description tags are defined as follows:</p>
<h4><a name="256.3.0"><li><tt>database</tt></li></a></h4>
<p>The <tt>database</tt> tag should be always at the top of the schema object hierarchy.  Currently it may contain the definition of two types of objects:  <tt>table</tt> and <tt>sequence</tt>.</p>
<p>The <tt>database</tt> schema object may have the following properties:</p>
<ul>
<p><li><tt>name</tt></li> (required)</p>
<p>Name of the database that is meant to be created when it is installed for the first time.</p>
<p><b>Default:</b> none</p>
<p><li><tt>create</tt></li></p>
<p>Boolean flag that indicates whether the database manager class should create the specified database or use a previously installed database of the same name.</p>
<p>This property may have to be set to <tt>0</tt> if you are splitting your database definition in multiple schema description files and only the installation of the first description file is supposed to lead to the actual database creation operation.</p>
<p>Another circumstance on which this property may have to be set to <tt>0</tt> is when the <i>DBMS</i> driver does not support database creation or if this operation requires special database administrator permissions that may not be available to the database user.</p>
<p><b>Default:</b> <tt>0</tt></p>
<p><li><tt>description</tt></li></p>
<p>Free text property meant for describing the purpose of the database. This field is not processed by the schema parser. It may contain text or other XML well formed tags that may be useful for embedding additional data structures for documentation applications or other purposes.</p>
<p><b>Default:</b> none</p>
<p><li><tt>comments</tt></li></p>
<p>Additional database comments. This field is not processed by the schema parser. It may contain text or other XML well formed tags that may be useful for embedding additional data structures for documentation applications or other purposes.</p>
<p><b>Default:</b> none</p>
</ul>
<h4><a name="257.3.1"><li><tt>table</tt></li></a></h4>
<p>The <tt>table</tt> is one of the main database schema objects.  It may be used in a schema description multiple times, once per each table that is contained the database being described.</p>
<p>The <tt>table</tt> object definition may contain the <tt>declaration</tt> and <tt>initialization</tt> sections besides the properties.  The <tt>table</tt> schema object may have the following properties:</p>
<ul>
<p><li><tt>name</tt></li> (required)</p>
<p>Name of the table.</p>
<p><b>Default:</b> none</p>
<p><li><tt>was</tt></li></p>
<p>Name that the table had before the last time it was renamed. This property is only meant to be used when the database is being upgraded and the table is meant to be renamed.</p>
<p>Beware that if this property is not specified and the <tt>name</tt> is changed, that is intended as if it is meant to drop the table with the previous name and create a new table without keeping the data that was previously stored in the table.</p>
<p><b>Default:</b> none</p>
<p><li><tt>description</tt></li></p>
<p>Free text property meant for describing the purpose of the table. This field is not processed by the schema parser. It may contain text or other XML well formed tags that may be useful for embedding additional data structures for documentation applications or other purposes.</p>
<p><b>Default:</b> none</p>
<p><li><tt>comments</tt></li></p>
<p>Additional table comments. This field is not processed by the schema parser. It may contain text or other XML well formed tags that may be useful for embedding additional data structures for documentation applications or other purposes.</p>
<p><b>Default:</b> none</p>
</ul>
<p>Example:</p>
<ul>
<p><tt>&lt;table&gt;</tt></p>
<ul>
<p><tt>&lt;name&gt;users&lt;/name&gt;</tt></p>
<p><tt>&lt;declaration&gt;</tt></p>
<ul>
<p><tt>&lt;field&gt;</tt></p>
<ul>
<p><tt>&lt;name&gt;id&lt;/name&gt;</tt><br />
 <tt>&lt;type&gt;integer&lt;/type&gt;</tt><br />
 <tt>&lt;notnull&gt;1&lt;/notnull&gt;</tt><br />
 <tt>&lt;default&gt;0&lt;/default&gt;</tt></p>
</ul>
<p><tt>&lt;/field&gt;</tt><br />
 <tt>&lt;field&gt;</tt></p>
<ul>
<p><tt>&lt;name&gt;name&lt;/name&gt;</tt><br />
 <tt>&lt;type&gt;text&lt;/type&gt;</tt><br />
 <tt>&lt;length&gt;&lt;variable&gt;name_length&lt;/variable&gt;&lt;/length&gt;</tt></p>
</ul>
<p><tt>&lt;/field&gt;</tt></p>
</ul>
<p><tt>&lt;/declaration&gt;</tt><br />
 <tt>&lt;initialization&gt;</tt></p>
<ul>
<p><tt>&lt;insert&gt;</tt></p>
<ul>
<p><tt>&lt;field&gt;</tt></p>
<ul>
<p><tt>&lt;name&gt;id&lt;/name&gt;</tt><br />
 <tt>&lt;value&gt;1&lt;/value&gt;</tt></p>
</ul>
<p><tt>&lt;/field&gt;</tt><br />
 <tt>&lt;field&gt;</tt></p>
<ul>
<p><tt>&lt;name&gt;name&lt;/name&gt;</tt><br />
 <tt>&lt;value&gt;administrator&lt;/value&gt;</tt></p>
</ul>
<p><tt>&lt;/field&gt;</tt></p>
</ul>
<p><tt>&lt;/insert&gt;</tt></p>
</ul>
<p><tt>&lt;/initialization&gt;</tt></p>
</ul>
<p><tt>&lt;/table&gt;</tt></p>
</ul>
<h4><a name="267.3.2"><li><tt>declaration</tt></li></a></h4>
<p><tt>declaration</tt> is one of the sections that is part of the table definition.  This section is required because it must contain the definition of the table <tt>field</tt> and <tt>index</tt> objects.</p>
<h4><a name="267.3.3"><li><tt>field</tt></li></a></h4>
<p><tt>field</tt> is one of the types of table definition object. It should be specified within the table declaration section for each field that the table should contain.</p>
<p>The <tt>field</tt> schema object may have the following properties:</p>
<ul>
<p><li><tt>name</tt> (required)</li></p>
<p>Name of the field.</p>
<p><b>Default:</b> none</p>
<p><li><tt>was</tt></li></p>
<p>Name that the field had before the last time it was renamed. This property is only meant to be used when the database is being upgraded and the field is meant to be renamed.</p>
<p><b>Default:</b> none</p>
<p><li><tt>type</tt> (required)</li></p>
<p>Type of the field.  Valid type values are: <tt>integer</tt>, <tt>text</tt>, <tt>boolean</tt>, <tt>date</tt>, <tt>timestamp</tt>, <tt>time</tt>, <tt>float</tt>, <tt>decimal</tt>, <tt>clob</tt> and <tt>blob</tt>.</p>
<p><b>Default:</b> none</p>
<p><li><tt>default</tt></li></p>
<p>Default value for the field.  The allowed values depend on the type of the field.  If this property is not specified the default value is assumed to be <tt>NULL</tt>.  If there is a table index on the field being declared, the <tt>default</tt> value must be specified because indexes can not be created on table fields with <tt>NULL</tt> values.</p>
<p>Notice that some low end <i>DBMS</i> do not support specifying default values in the field definition.  Make sure that the you either specify all the values for each new row that is inserted in the tables or that the <i>DBMS</i> actually supports default values.</p>
<p>Only some <i>DBMS</i> support default values for large object fields. For this reason it is not allowed to specify default values on the definition of this type of field.</p>
<p><b>Default:</b> none</p>
<p><li><tt>notnull</tt></li></p>
<p>Boolean flag property that specifies whether the table field should be created with the constraint <tt>NOT NULL</tt>.  As it suggests, this implies that it is not allowed to set this field value with <tt>NULL</tt>.  The parser does not allow that an index is declared on a field that is not declared with the <tt>notnull</tt> flag property.</p>
<p><b>Default:</b> <tt>0</tt></p>
<p><li><tt>unsigned</tt></li></p>
<p>Boolean flag property that specifies whether an integer field should be declared as unsigned integer.  Note that some <i>DBMS</i> do not support unsigned integer fields.  In such case the <i>DBMS</i> driver will ignore this property but it issues a warning.</p>
<p><b>Default:</b> <tt>0</tt></p>
<p><li><tt>length</tt></li></p>
<p>Unsigned integer property that specifies the length of a text.  If this property is specified the text field may not have a longer length.  Text values shorter than the length are not padded.  If this property is not specified the length limit is determined by the <i>DBMS</i>.</p>
<p><b>Default:</b> none</p>
<p><li><tt>autoincrement</tt></li></p>
<p>Boolean flag property that specifies whether the table field should be an auto-incremented key field. Setting this property to <tt>1</tt> implicitly sets other properties of the field: <tt>type</tt> to <tt>integer</tt>, <tt>unsigned</tt> to <tt>1</tt>, <tt>notnull</tt> to <tt>1</tt>, <tt>default</tt> to <tt>0</tt>, and also define the table primary key to this field if the table primary key is not defined.</p>
<p><b>Default:</b> none</p>
<p><li><tt>description</tt></li></p>
<p>Free text property meant for describing the purpose of the field. This field is not processed by the schema parser. It may contain text or other XML well formed tags that may be useful for embedding additional data structures for documentation applications or other purposes.</p>
<p><b>Default:</b> none</p>
<p><li><tt>comments</tt></li></p>
<p>Additional field comments. This field is not processed by the schema parser. It may contain text or other XML well formed tags that may be useful for embedding additional data structures for documentation applications or other purposes.</p>
<p><b>Default:</b> none</p>
</ul>
<p>Example:</p>
<ul>
<p><tt>&lt;field&gt;</tt></p>
<ul>
<p><tt>&lt;name&gt;id&lt;/name&gt;</tt><br />
 <tt>&lt;type&gt;integer&lt;/type&gt;</tt><br />
 <tt>&lt;notnull&gt;1&lt;/notnull&gt;</tt><br />
 <tt>&lt;default&gt;0&lt;/default&gt;</tt></p>
</ul>
<p><tt>&lt;/field&gt;</tt><br />
</p>
</ul>
<h4><a name="270.3.4"><li><tt>index</tt></li></a></h4>
<p><tt>index</tt> is another type of table definition object. It should also be specified within the table declaration section.</p>
<p>The <tt>index</tt> schema object may have the following properties:</p>
<ul>
<p><li><tt>name</tt> (required)</li></p>
<p>Name of the index.</p>
<p>Only some <i>DBMS</i> support indexes on large object fields. For this reason it is not allowed to specify a large object field for indexes.</p>
<p><b>Default:</b> none</p>
<p><li><tt>was</tt></li></p>
<p>Name that the index had before the last time it was renamed. This property is only meant to be used when the database is being upgraded and the field is meant to be renamed.</p>
<p><b>Default:</b> none</p>
<p><li><tt>unique</tt></li></p>
<p>Boolean flag property that specifies whether the combination of the values of the index fields on each row of the table should unique.</p>
<p><b>Default:</b> <tt>0</tt></p>
</ul>
<h4><a name="271.3.5"><li>index <tt>field</tt></li></a></h4>
<p><tt>field</tt> is a section that is part of the table index declaration.  It should be used once per each field on which the index should be created.</p>
<p>The index <tt>field</tt> declaration may have the following properties:</p>
<ul>
<p><li><tt>name</tt> (required)</li></p>
<p>Name of the field on which the index should be created.</p>
<p><b>Default:</b> none</p>
<p><li><tt>sorting</tt></li></p>
<p>Type of field sorting that should be assumed when the index is created.  On <i>DBMS</i> that support index sorting, queries that search tables on the fields specified by the given index may execute faster if the specified sorting type is chosen adequately.  <i>DBMS</i> that do not support index sorting will ignore this property.</p>
<p>Valid sorting types are <tt>ascending</tt> and <tt>descending</tt>.</p>
<p><b>Default:</b> none</p>
</ul>
<p>Example:</p>
<ul>
<p><tt>&lt;index&gt;</tt></p>
<ul>
<p><tt>&lt;name&gt;users_index&lt;/name&gt;</tt><br />
 <tt>&lt;field&gt;</tt></p>
<ul>
<p><tt>&lt;name&gt;id&lt;/name&gt;</tt><br />
 <tt>&lt;sorting&gt;ascending&lt;/sorting&gt;</tt></p>
</ul>
<p><tt>&lt;/field&gt;</tt></p>
</ul>
<p><tt>&lt;/index&gt;</tt><br />
</p>
</ul>
<h4><a name="275.3.6"><li><tt>primarykey</tt></li></a></h4>
<p><tt>primarykey</tt> is another type of table definition object. It should also be specified within the table declaration section.</p>
<p>The <tt>primarykey</tt> schema object only contains one or more sections that define the fields the define the table primary key. Each field section starts with the field tag and its definition is the same for normal table index fields.</p>
<p>If the table contains an auto-incremented key field, automatically the primary key definition is associated to that field. Therefore, the primary key definition becomes redundant unless its definition includes other fields besides the table auto-incremented key field.</p>
<p>Example:</p>
<ul>
<p><tt>&lt;primarykey&gt;</tt></p>
<ul>
<p><tt>&lt;field&gt;</tt></p>
<ul>
<p><tt>&lt;name&gt;id&lt;/name&gt;</tt><br />
 <tt>&lt;sorting&gt;ascending&lt;/sorting&gt;</tt></p>
</ul>
<p><tt>&lt;/field&gt;</tt></p>
</ul>
<p><tt>&lt;/primarykey&gt;</tt><br />
</p>
</ul>
<h4><a name="278.3.7"><li><tt>initialization</tt></li></a></h4>
<p><tt>initialization</tt> is another section that is part of the table definition.  This section is optional and may contain the definition of actions that should be executed when installing the database for the first time.  Currently the only action that is supported is <tt>insert</tt>.</p>
<h4><a name="278.3.8"><li><tt>insert</tt></li></a></h4>
<p><tt>insert</tt> is a table initialization command that specifies the values of the fields of rows that should be inserted in the respective table after the database is created for the first time.</p>
<p>The <tt>insert</tt> command definition only contains one more <tt>field</tt> sections with <tt>name</tt> and <tt>value</tt> pairs that indicate the values of the fields are explicitly initialized when the new row is inserted.  Missing fields are implicitly initialized by the <i>DBMS</i> with the respective default values.</p>
<h4><a name="278.3.9"><li><tt>sequence</tt></li></a></h4>
<p>The <tt>sequence</tt> is another main database schema object.  It may be used in a schema description multiple times, once per each sequence that is contained the database being described.</p>
<p>A <tt>sequence</tt> is an object that only contains an integer value.  A sequence value is automatically incremented after every time it is fetch the next sequence value.  The fetch and increment actions constitute an atomic operation.  This means that if two concurrent accesses to the database fetch the next sequence value, they will always different values.</p>
<p>Sequences are useful to generate integer numbers that may be used to store in fields that must contain unique numbers.</p>
<p>The <tt>sequence</tt> object definition may contain one <tt>on</tt> section besides the properties.  The <tt>sequence</tt> schema object may have the following properties:</p>
<ul>
<p><li><tt>name</tt></li> (required)</p>
<p>Name of the sequence.</p>
<p><b>Default:</b> none</p>
<p><li><tt>was</tt></li></p>
<p>Name that the sequence had before the last time it was renamed. This property is only meant to be used when the database is being upgraded and the sequence is meant to be renamed.</p>
<p><b>Default:</b> none</p>
<p><li><tt>start</tt></li></p>
<p>Integer property that specifies the value that the sequence will return when it is fetched the next sequence value.</p>
<p><b>Default:</b> none</p>
<p><li><tt>description</tt></li></p>
<p>Free text property meant for describing the purpose of the sequence. This field is not processed by the schema parser. It may contain text or other XML well formed tags that may be useful for embedding additional data structures for documentation applications or other purposes.</p>
<p><b>Default:</b> none</p>
<p><li><tt>comments</tt></li></p>
<p>Additional table comments. This field is not processed by the schema parser. It may contain text or other XML well formed tags that may be useful for embedding additional data structures for documentation applications or other purposes.</p>
<p><b>Default:</b> none</p>
</ul>
<h4><a name="279.3.10"><li>sequence <tt>on</tt> table field</li></a></h4>
<p>The sequence <tt>on</tt> <tt>table</tt> <tt>field</tt> section specifies a table field on which the sequence value should be synchronized.</p>
<p>This information is meant to be used only by the database manager class when it is added a sequence later after the database has been installed for the first time.  If the sequence <tt>on</tt> is specified, the database manager class will override the sequence <tt>start</tt> value with a value that is higher than the highest value in the specified field table.  Therefore, the specified field table type must be integer.</p>
<p>Example:</p>
<ul>
<p><tt>&lt;sequence&gt;</tt></p>
<ul>
<p><tt>&lt;name&gt;users_sequence&lt;/name&gt;</tt><br />
 <tt>&lt;start&gt;1&lt;/start&gt;</tt><br />
 <tt>&lt;on&gt;</tt></p>
<ul>
<p><tt>&lt;field&gt;id&lt;/field&gt;</tt><br />
 <tt>&lt;table&gt;users&lt;/table&gt;</tt></p>
</ul>
<p><tt>&lt;/on&gt;</tt></p>
</ul>
<p><tt>&lt;/sequence&gt;</tt><br />
</p>
</ul>
<h4><a name="282.3.11"><li><tt>variable</tt></li></a></h4>
<p>The <tt>variable</tt> tag is not meant to define any database schema object but rather a means to replace property values with variables defined at parsing time.</p>
<p>For instance, if you have several tables that store user names in text fields with the same length limit, instead of hard coding the length value in all field definitions, you may use a variable reference.  The parser will replace variable references found in property definitions by the text values of the respective values passed to the parser.</p>
<p>The parser will issue an error if the it is referenced a variable that is not defined.</p>
</ul>
<h3><a name="282.2.3"><li>Schema description parser class</li></a></h3>
<ul>
<p>The schema description parser is a class that is able to build a data structure that describes database schema objects by parsing a schema description.</p>
<p>The objects of this class are initialized like the objects of other classes, i.e., using the <tt>new</tt> operator:</p>
<p><tt>$parser_object=new metabase_parser_class;</tt></p>
<h4><li><a name="283.3.1">Functions</a></li></h4>
<ul>
<h5><a name="284.4.0">Parse</a></h5>
<ul>
<h6>Synopsis</h6>
<p><tt>$error=$parser_object-&gt;Parse($data, $end_of_data)</tt></p>
<h6>Purpose</h6>
<p>Parse schema description to build a data structure that describes database schema objects.</p>
<h6>Usage</h6>
<p>The <tt>$data</tt> argument is a string that contains the contents of all or part of the schema description XML data. This function may be call once or more times to feed consecutive chunks of schema description until the whole XML data and been fed to the parser.</p>
<p>The resulting schema description data structure is stored in the object <tt>database</tt> variable.</p>
<p>The <tt>$end_of_data</tt> argument is a boolean flag that indicates whether the data being passed to the parse is the last (or probably the only) chunk of the schema description being passed.</p>
<p>The <tt>$error</tt> result value is a string that describes the error that occurred if this function call fails.  If it succeeds, the function returns an empty string.</p>
</ul>
<h5><a name="285.4.0">ParseStream</a></h5>
<ul>
<h6>Synopsis</h6>
<p><tt>$error=$parser_object-&gt;ParseStream($stream)</tt></p>
<h6>Purpose</h6>
<p>Parse schema description by calling the <tt>Parse</tt> function by reading the input from an opened stream until it reaches its end.</p>
<h6>Usage</h6>
<p>The <tt>$stream</tt> argument is an identifier for an opened stream that may be an opened file, network connection, etc..</p>
<p>The <tt>$error</tt> result value is a string that describes the error that occurred if this function call fails.  If it succeeds, the function returns an empty string.</p>
</ul>
</ul>
<h4><li><a name="286.3.2">Variables</a></li></h4>
<p>The objects of this class have several public variables that contain additional information beside what is returned by the class functions.</p>
<ul>
<p><li><a name="287.4.1"><tt>stream_buffer_size</tt></a></li></p>
<p>Integer value that holds the size of the buffer into which the <tt>ParseStream</tt> function reads the chunks of the schema description input data.  The default value is <tt>4096</tt>.</p>
<p><li><a name="287.4.2"><tt>error_number</tt></a></li></p>
<p>Integer value that holds the error number that resulted from the last failed call to the class functions.  The currently defined values are:</p>
<ul>
<p><tt>0</tt> - No error</p>
<p><tt>1</tt> - Could not parse data</p>
<p><tt>2</tt> - Could not read from input stream</p>
<p><tt>3</tt> - Metabase format syntax error</p>
<p><tt>4</tt> - Variable not defined</p>
</ul>
<p><li><a name="288.4.3"><tt>error</tt></a></li></p>
<p>Text value that holds the error number that resulted from the last failed call to the class functions.</p>
<p><li><a name="288.4.4"><tt>error_line</tt></a></li></p>
<p>Integer value that holds the number of the line of the schema description input data that originated the error that resulted from the last failed call to the class functions.</p>
<p><li><a name="288.4.5"><tt>error_column</tt></a></li></p>
<p>Integer value that holds the number of the column of the schema description input data that originated the error that resulted from the last failed call to the class functions.</p>
<p><li><a name="288.4.6"><tt>error_byte_index</tt></a></li></p>
<p>Integer value that holds the number of byte of the schema description input data that originated the error that resulted from the last failed call to the class functions.</p>
<p><li><a name="288.4.7"><tt>variables</tt></a></li></p>
<p>Associative array that holds the list of variable names and their respective values that should be used to replace variable reference of the data of schema object properties.</p>
<p><li><a name="288.4.8"><tt>fail_on_invalid_names</tt></a></li></p>
<p>Boolean flag value that indicates whether the parser should fail when it parses a schema object with a name that is potentially invalid, i.e., it may not be accepted by all <tt>DBMS</tt>.</p>
<p><li><a name="288.4.9"><tt>database</tt></a></li></p>
<p>Associative array that contains the data structure that describes the database schema objects after calling the <tt>Parse</tt> function.  The contents of this array reflect the structure of the data in database schema definitions XML input data.</p>
</ul>
</ul>
</ul>
</ul>
<hr />
<h1><a name="database_manager"></a><a name="288.0">Database manager</a></h1>
<ul>
<p>The database manager is a class that provides a set of database management services like installing, altering and dumping the data structures of databases.</p>
<p>The objects of this class are initialized like the objects of other classes, i.e., using the <tt>new</tt> operator:</p>
<p><tt>$manager_object=new metabase_manager_class;</tt></p>
<h2><li><a name="289.1.1">Functions</a></li></h2>
<ul>
<h3><a name="290.2.0">AlterDatabase</a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=$manager_object-&gt;AlterDatabase(&amp;$previous_definition, &amp;$changes)</tt></p>
<h4>Purpose</h4>
<p>Execute the necessary actions to implement the requested changes in a database structure.</p>
<h4>Usage</h4>
<p>The <tt>$previous_definition</tt> argument is an associative array that contains the definition of the database structure before applying the requested changes.  The definition of this array may be built separately, but usually it is built by the <tt>Parse</tt> method the <b>Metabase</b> parser class.</p>
<p>The <tt>$changes</tt> argument is an associative array that contains the definition of the changes that are meant to be applied to the database structure.</p>
<p>The <tt>$error</tt> result value is a string that describes the error that occurred if this function call fails.  If it succeeds, the function returns an empty string.</p>
</ul>
<h3><a name="291.2.0">DumpDatabase</a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=$manager_object-&gt;DumpDatabase($arguments)</tt></p>
<h4>Purpose</h4>
<p>Dump a previously parsed database structure in the <b>Metabase</b> schema XML based format suitable for the <b>Metabase</b> parser.  This function may optionally dump the database definition with initialization commands that specify the data that is currently present in the tables.</p>
<h4>Usage</h4>
<p>The <tt>$arguments</tt> argument is an associative array that takes pairs of tag names and values that define dump options. Currently, the supported option arguments are as follows:</p>
<ul>
<p><tt><li>Output</li></tt> (required)</p>
<p>Name of the global function that is meant to be called to output the database dump.  The function will only take a string argument that contains that text that defined the dump.</p>
<p><b>Default value:</b> not specified</p>
<p><tt><li>EndOfLine</li></tt></p>
<p>String that defines how the lines of the dump are meant to be broken.</p>
<p><b>Default value:</b> a single new line character</p>
<p><tt><li>Definition</li></tt></p>
<p>Option that indicates whether it is intended to dump the data of the database tables as initialization commands.</p>
<p><b>Default value:</b> not defined</p>
</ul>
<p>The <tt>$error</tt> result value is a string that describes the error that occurred if this function call fails.  If it succeeds, the function returns an empty string.</p>
</ul>
<h3><a name="293.2.0">ParseDatabaseDefinitionFile</a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=$manager_object-&gt;ParseDatabaseDefinitionFile($input_file, &amp;$database_definition, &amp;$variables)</tt></p>
<h4>Purpose</h4>
<p>Parse a database definition file by creating a <b>Metabase</b> schema format parser object and passing the file contents as parser input data stream.</p>
<h4>Usage</h4>
<p>The <tt>$input_file</tt> argument is the path of the database schema file.</p>
<p>The <tt>$database_definition</tt> argument is a reference to an associative array that will hold the information about the database schema structure as return by the parser object.</p>
<p>The <tt>$variables</tt> argument is an associative array that the defines the text string values that are meant to be used to replace the variables that are used in the schema description.</p>
<p>The <tt>$error</tt> result value is a string that describes the error that occurred if this function call fails.  If it succeeds, the function returns an empty string.</p>
</ul>
<h3><a name="294.2.0">DumpDatabaseChanges</a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$manager_object-&gt;DumpDatabaseChanges(&amp;$changes, $function)</tt></p>
<h4>Purpose</h4>
<p>Dump the changes between two database definitions.</p>
<h4>Usage</h4>
<p>The <tt>$changes</tt> argument is an associative array that specifies the list of database definitions changes as returned by the <tt>CompareDefinitions</tt> manager class function.</p>
<p>The <tt>$function</tt> argument is the name of the global function that is meant to be called to output the database changes dump.  The function will only take a string argument that contains that text that defined the dump.</p>
</ul>
<h3><a name="295.2.0">UpdateDatabase</a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$success=$manager_object-&gt;UpdateDatabase($current_schema_file, $previous_schema_file, $arguments, $variables, $check)</tt></p>
<h4>Purpose</h4>
<p>Compare the corresponding files of two versions of a database schema definition:  the previously installed and the one that defines the schema that is meant to update the database.</p>
<p>If the specified previous definition file does not exist, this function will create the database from the definition specified in the current schema file.</p>
<p>If both files exist, the function assumes that the database was previously installed based on the previous schema file and will update it by just applying the changes.</p>
<p>If this function succeeds, the contents of the current schema file are copied to replace the previous schema file contents. Any subsequent schema changes should only be done on the file specified by the <tt>$current_schema_file</tt> to let this function make a consistent evaluation of the exact changes that need to be applied.</p>
<h4>Usage</h4>
<p>The <tt>$current_schema_file</tt> argument is the name of the updated database schema definition file.</p>
<p>The <tt>$previous_schema_file</tt> argument is the name the previously installed database schema definition file.</p>
<p>The <tt>$arguments</tt> argument is an associative array that takes pairs of tag names and values that define the setup arguments that are passed to the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$variables</tt> argument is an associative array that is passed to the argument of the same name to the <tt>ParseDatabaseDefinitionFile</tt> function.</p>
<p>The <tt>$success</tt> result value is boolean flag that indicates whether this function call succeeded.  If it failed, the object variable <tt>error</tt> contains the text string of the error that occurred.</p>
</ul>
<h3><a name="296.2.0"><a name="function_DumpDatabaseContents">DumpDatabaseContents</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=$manager_object-&gt;DumpDatabaseContents($schema_file, &amp;$setup_arguments, &amp;$dump_arguments,&amp; $variables)</tt></p>
<h4>Purpose</h4>
<p>Parse a database schema definition file and dump the respective structure and contents.</p>
<h4>Usage</h4>
<p>The <tt>$schema_file</tt> argument is the path of the database schema file.</p>
<p>The <tt>$setup_arguments</tt> argument is an associative array that takes pairs of tag names and values that define the setup arguments that are passed to the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$dump_arguments</tt> argument is an associative array that takes pairs of tag names and values that define dump options as defined for the <tt>DumpDatabase</tt> function.</p>
<p>The <tt>$variables</tt> argument is an associative array that the defines the text string values that are meant to be used to replace the variables that are used in the schema description as defined for the <tt>ParseDatabaseDefinitionFile</tt> function.</p>
<p>The <tt>$error</tt> result value is a string that describes the error that occurred if this function call fails.  If it succeeds, the function returns an empty string.</p>
</ul>
<h3><a name="297.2.0"><a name="function_GetDefinitionFromDatabase">GetDefinitionFromDatabase</a></a></h3>
<ul>
<h4>Synopsis</h4>
<p><tt>$error=$manager_object-&gt;GetDefinitionFromDatabase($arguments)</tt></p>
<h4>Purpose</h4>
<p>Retrieve the schema definition of the current database using reverse engineering functions of <b>Metabase</b> API.</p>
<h4>Usage</h4>
<p>This function reverse engineers the definition of the current database and stores it class variable <tt>database_definition</tt>. After successfully executing the <tt>GetDefinitionFromDatabase</tt> function , you may call the <tt><a href="#function_DumpDatabaseContents">DumpDatabaseContents</a></tt> to output the database schema definition in the XML format.</p>
<p>A script named <tt>get_database.php</tt> is provided with <b>Metabase</b> distribution to use these functions to dump database schemas in the XML format.</p>
<p>The <tt>$arguments</tt> argument is a reference to an associative array variable that has pairs of tag names and values that define the setup arguments that are passed to the <tt><a href="#function_MetabaseSetupDatabase">MetabaseSetupDatabase</a></tt> function.</p>
<p>The <tt>$error</tt> result value is a string that describes the error that occurred if this function call fails.  If it succeeds, the function returns an empty string.</p>
</ul>
</ul>
<h2><li><a name="298.1.2">Variables</a></li></h2>
<p>The objects of this class have several public variables that contain additional information beside what is returned by the class functions.</p>
<ul>
<p><li><a name="299.2.1"><tt>fail_on_invalid_names</tt></a></li></p>
<p>The schema parser class variable of the same name is set with the value of the option variable before parsing new schema descriptions.  Refer to the schema parser variable description to understand its meaning.</p>
<p><b>Default value:</b> <tt>1</tt></p>
<p><li><a name="299.2.2"><tt>error</tt></a></li></p>
<p>Text value that holds an error string that may result from failure of the <tt>UpdateDatabase</tt> function call.</p>
<p><li><a name="299.2.3"><tt>warnings</tt></a></li></p>
<p>Array that holds a list of warning messages that may result from unexpected situations that should be paid attention.</p>
<p><li><a name="299.2.4"><tt>database_definition</tt></a></li></p>
<p>Associative array that holds the definition of the current database schema.</p>
</ul>
</ul>

<hr />
<address>Manuel Lemos (<a href="mailto:mlemos-at-acm.org">mlemos-at-acm.org</a>)</address>
</body>
</html>
